Python爬虫

第一个小测试,认识爬虫

1
2
3
4
5
6
7
8
9
10
11
12
13
# 爬虫:通过编写程序来获取到互联网上的资源
# 百度
# 需求:用哪个程序模拟浏览器,输入一个网址,从中获取资源或者内容

from urllib.request import urlopen

url = "http://www.baidu.com"
resp = urlopen(url)

with open("mybaidu.html", mode="w", encoding= "utf-8")as f:
f.write(resp.read().decode("utf-8"))
print("over")
resp.close() # 关闭resp

Web请求剖析

1
2
3
4
5
# 1. 服务器渲染:在服务器那边直接把数据和html整合在一起,同意返回给浏览器
# 在页面源代码代码中可以看到数据
# 2. 客户端渲染:第一次请求只要html骨架,第二次请求拿到数据进行数据展示,
# 在页面源码中,看不到数据
# 熟悉页面抓包

HTTP协议

  1. User-Agent:请求载体的身份标识用啥发送的请求
  2. Referer防盗捱(这次请求是从哪个页面来的?反爬会用到3. cookie:本地字符串数据信息(用户登录信息,反爬的token)
  3. 响应头中一些重要的内容:
    1. cockie:本地字符串数据信忌(用户登录信忌,反贬的token
    2. 各种神奇的莫名其妙的字符串{这个需要经验了.一般都是token字样.防止各种攻击和反吗)
  4. 请求方式:
    1. get
    2. post

requests 模块

入门

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 安装requests
# pip install requests
# 国内原
# 清华源 阿里源等

import requests

query = input("输入一个人名")

url = f'https://cn.bing.com/search?q={query}'

rep=requests.get(url)

print(rep)
print(rep.text)
resp.close() # 关闭resp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import requests

url = 'https://fanyi.baidu.com/sug'

s = input("输入你需要翻译的英文")

dat = {
"kw":s
}

# 发送post请求 ,发送的数据放在字典中,通过data参数进行传递
resp = requests.post(url,data=dat)
print(resp.json()) #讲服务器的内容直接处理成字典
resp.close() # 关闭resp

抓取豆瓣,某些数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import requests

url = 'https://movie.douban.com/j/chart/top_list'


headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36 Core/1.94.177.400 QQBrowser/11.3.5194.400"
}
# 重新封装
palam = {
"type": "13",
"interval_id": "100:90",
"action": "",
"start": "0",
"limit": "20"
}

resp = requests.get(url= url, params=palam, headers=headers)

print(resp.text)
resp.close() # 关闭resp

数据解析

  1. re解析
  2. bs4解析
  3. xpath解析

re模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# re模块
import re

# findall 匹配字符串中所有符合正则的内容
# finditer 匹配字符串中所有内容【返回的是迭代器】,找到一个结果就返回,从迭代器中拿到内容需要.group()
lst= re.findall(r"\d+", "我的电话是10010,你的电话是10086")
print(lst)


it = re.finditer(r"\d+", "我的电话是10010,你的电话是10086")
for i in it:
print(i.group())


# search返回结果是match对象,找到一个结果只返回第一个结果
s = re.search(r"\d+", "我的电话是10010,你的电话是10086")
print(s.group())

# match从头开始匹配
m = re.match(r"\d+", "我的电话是10010,你的电话是10086")
print(m.group())

# 预加载正则表达式
obj = re.compile(r"\d+")

ret = obj.finditer("我的电话是10010,你的电话是10086")
for it in ret:
print(it.group())

案例

豆瓣top250抓取信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 手忍豆瓣排行榜
# 拿到页面源代码 . request
# 通过re来提取想要的有效信息
import requests
import re
import csv

url = 'https://movie.douban.com/top250'
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36 Core/1.94.177.400 QQBrowser/11.3.5194.400"
}
resp = requests.get(url,headers = headers,)
resp.encoding = "UTF-8"
page_content = resp.text

# 解析数据
obj = re.compile(r'<li>.*?<div class="item">.*?<span class="title">(?P<name>.*?)</span>'
r'.*?<p class="".*?<br>(?P<year>.*?)&nbsp.*?<span class="rating_num" property="v:average">'
r'(?P<score>.*?)</span>.*?<span>(?P<num>.*?)人评价</span>',re.S)

# 开始匹配
result = obj.finditer(page_content)
f = open("data.csv", mode="w")
csvwriter = csv.writer(f)
for it in result:
# print(it.group("name"))
# print(it.group("score"))
# print(it.group("num"))
# print(it.group("year").strip())
dic = it.groupdict()
dic['year'] = dic['year'].strip()
csvwriter.writerow(dic.values())


f.close()
print("end of")

bs4解析 - HTML编码

  1. 安装
    1. pip install bs4 -i

搞搞菜价 – 北京新发地

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# bs4
# 拿到页面源代码
# 使用bs4进行解析,拿到数据

import requests
import re
from bs4 import BeautifulSoup
import csv


url = 'http://www.xinfadi.com.cn/priceDetail.html'
resp = requests.get(url)

f = open("菜价.csv", mode="w")
scw = csv.writer(f)

# 解析数据
# 吧页面源码交给BeautifulSoup进行处理,生成bs对象
page = BeautifulSoup(resp.text, 'html.parser')
# 从bs对象中查找数据
# dind(标签,属性=值)
# dind_all(标签,属性=值)

# table = page.find('div', class_="tablebox") # class关键字在后面加上一个下划线_
table = page.find('tbody', attrs={
"id": "tableBody"
}) # class关键字在后面加上一个下划线_
# print(table)
# 拿到所有的数据行
trs = table.find_all("tr")[1:]
for tr in trs: # 每一样
tds = tr.find_all("td")
sb1 = tds[0].text # .text 表示拿到被标签标记的内容
sb2 =tds[1].text # .text 表示拿到被标签标记的内容
sb3 = tds[2].text # .text 表示拿到被标签标记的内容
sb4 = tds[3].text # .text 表示拿到被标签标记的内容
sb5 = tds[4].text # .text 表示拿到被标签标记的内容
sb6 = tds[5].text # .text 表示拿到被标签标记的内容
sb7 = tds[6].text # .text 表示拿到被标签标记的内容
csv.writerow([sb1, sb2, sb3, sb4, sb5, sb6, sb7])

f.close()
print("end of")