requests模块作为爬虫中最常用的一个模块,我们必须要拿捏它。
requests模块我会给大家分享以下的知识点
- requests的简单使用
- 发送带header的请求
- 发送带参数的请求
- 发送POST请求
- cookies参数的使用
- 代理ip参数proxies
- 超时参数timeout的使用
- 使用verify参数忽略CA证书
可能之前看过一些教程的小可爱在想,为什么不是从urllib开始,而是从requests模块开始,原因有以下几点
- 1.requests的底层实现就是urllib
- 2.requests在Python2和Python3通用,方法完全一样
- 3.requests简单易用
requests的作用
作用:发送网络请求,返回相应数据
发送简单的get请求
# 导入模块
import requests
# 要发送请求的URL地址
url = 'https://www.baidu.com'
# 发送get请求
response = requests.get(url)
如果想要获取服务器返回的响应也比较简单
print(response.text)
用text方法来获取响应,可能会存在编码的问题,因为response.text是requests模块按照chardet模块推测出的编码字符集进行解码的结果
那如何来解决这个编码问题呢?
response.encoding = 'utf-8'
这个时候在来请求的时候,发现编码就不会乱了,除了用text方法来获取响应之外,还可以用response.content.decode()
来获取响应
那response.text
和response.content
有什么区别吗?
response.text
- 类型:str
- 修改编码方式:response.encoding = ‘utf-8’
response.content
- 类型:bytes
- 修改编码方式:response.content.decode(‘utf8’)
response.content
也可以用来下载图片、音频,因为这些数据都是二进制的数据
import requests
response = requests.get('https://www.baidu.com/img/bd_logo1.png?where=super')
with open('baidu.png','wb') as f:
f.write(response.content)
response响应对象的其他常用属性和方法
response.status_code # 响应状态码
response.request.headers # 响应对应的请求头
response.headers # 响应头
response.json() # 自动将json字符串类型的响应内容转换为python对象
发送带header的请求
为什么请求需要带上header?
最主要的目的当然是,模拟浏览器,欺骗服务器,获取和浏览器一致的内容
header的形式:字典
headers = {'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36'}
用法:requests.get(url,headers = headers)
细心的小伙伴可能会发现我们刚才请求百度的时候,获取的代码特别少,如果我们打开百度页面的源码就会发现,百度的首页的源代码是非常多的。那我们刚才的代码也没有报错,为什么没有得到跟浏览器中一样的结果呢?
就是因为我们没有欺骗服务器,我们也是良民,不是爬虫。那具体怎么做呢,非常简单只要在发送请求的时候添加上请求头
import requests
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.75 Safari/537.36"
}
response = requests.get('https://www.baidu.com', headers=headers)
print(response.content.decode())
这个时候你就会发现,得到的响应代码会跟浏览器中一样。
发送带参数的请求
什么叫做请求参数,我们在百度搜索Python,你会发现URL地址特别长https://www.baidu.com/s?wd=Python&rsv_spt=1&rsv_iqid=0xcf3b76260008455f&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&rqlang=cn&tn=baiduhome_pg&rsv_enter=1&rsv_dl=tb&oq=%25E6%2588%2591%25E8%25A2%25AB%25E5%258F%2591%25E7%258E%25B0%25E4%25BA%2586%25E8%25A1%25A8%25E6%2583%2585%25E5%258C%2585&rsv_btype=t&rsv_t=13785XJdQmtJfz1EdkR7o%2F4vwyH5iqgvgEO0xje8y8hOOwyVF2l90CEvE7ArQsJIOwab&rsv_pq=924ae20300007ca1&inputT=1888&rsv_sug3=117&rsv_sug1=66&rsv_sug7=100&rsv_sug2=0&rsv_sug4=1968
在?后面的参数我们都可以叫做请求参数,那如果我们也想在requests模块中发送请求的时候带上参数,那我们应该如何做呢?
参数的形式:字典
kw = {'wd':'居然'}
用法:requests.get(url,params=kw)
使用起来非常的简单
bd_url = 'https://www.baidu.com/s'
kw = {
'wd':'居然'
}
headers = {
'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36'
}
r = requests.get(url,headers=headers,params=kw)
# 请求的URL地址
print(r.request.url)
发送POST请求
我们刚才用requests请求发送的都是get
请求,有些时候我们在请求网站的时候,会发现网站是post
请求。
一般那些地方我们会用到POST请求?
-
1 登录注册
-
2 需要传输大文本的时候
爬虫也需要在这两个地方模拟浏览器发送post
请求
data的形式:字典
用法:
response = requests.post("http://www.xxx.com/", data=data)
我们可以尝试找一些网站进行测试,但是很多网站在登录的时候,会对密码进行加密,会涉及到JS加密,我们这里以一个翻译网站作为案例
案例的网址:aHR0cHMlM0EvL2ZhbnlpLmJhaWR1LmNvbS90cmFuc2xhdGUlM0ZhbGR0eXBlJTNEMTYwNDclMjZxdWVyeSUzRCUyNTBEJTI1MEElMjUwRCUyNTBBJTI2a2V5ZnJvbSUzRGJhaWR1JTI2c21hcnRyZXN1bHQlM0RkaWN0JTI2bGFuZyUzRGF1dG8yemglMjNhdXRvL3poLw==
base64解码一下就好
import requests
headers = {
"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36",
"Cookie": "SOUND_SPD_SWITCH=1; REALTIME_TRANS_SWITCH=1; HISTORY_SWITCH=1; FANYI_WORD_SWITCH=1; SOUND_PREFER_SWITCH=1; APPGUIDE_10_0_2=1; BAIDUID=C48EC9F2B00CA95410C8A8",
"Referer: https://fanyi.baidu.com/translate?aldtype=16047&query=%0D%0A%0D%0A&keyfrom=baidu&smartresult=dict&lang=auto2zh"
}
data = {
'from': 'en',
'to': 'zh',
'query': 'hello',
'transtype': ' realtime',
'simple_means_flag': ' 3',
'sign': '54706.276099',
'token': '',
}
post_url = 'https://fanyi.baidu.com/v2transapi'
r = requests.post(post_url,data=post_data,headers=headers)
print(r.json())
cookies参数的使用
我们如果要爬取需要登录之后的数据,那我们在发送请求的时候,需要携带上cookie,cookie的获取也比较简单,我们先登录上网站,打开F12找到网站的cookie,接下来我们只需要在requests发送请求的时候携带上就可以了
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lvRvu7jQ-1667656829796)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/503a4050c58a481fa64694f8f4b18a2f~tplv-k3u1fbpfcp-watermark.image?)]
cookie我们可以添加到请求头中,也可以添加到requests中,接下来给大家分别演示一下。
cookie直接添加到请求头中
import requests
headers = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36",
# cookie直接添加到请求头中
"cookie": '2705185834_todaycount=0;'
}
r = requests.get('https://user.qzone.qq.com/xxx/infocenter?_t_=0.6841823472298363', headers=headers)
print(r.request.headers)
with open('qq1.html', 'w', encoding='utf-8') as f:
f.write(r.content.decode('utf-8'))
cookie作为requests的参数
import requests
headers = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36",
}
cookie = '2705185834_todaycount=0; '
cookie = {i.split("=")[0]: i.split("=")[1] for i in cookie.split("; ")}
r = requests.get('https://user.qzone.qq.com/xxx/infocenter?_t_=0.6841823472298363', headers=headers, cookies=cookie)
print(r.request.headers)
with open('qq2.html', 'w', encoding='utf-8') as f:
f.write(r.content.decode('utf-8'))
cookie和session区别
- cookie数据存放在客户端的浏览器上,session数据放在服务器上。
- cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗
- session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
- 单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie
使用代理
为什么爬虫需要使用代理IP呢?
-
1.让服务器以为不是同一个客户端在请求
-
2.防止我们的真实地址被泄露,防止被追究
用法:requests.get('http://www.baidu.com',proxies = proxies)
proxies的形式:字典
proxies = {
'http':'http://12.34.56.79:9527',
'https':'https://12.34.56.79:9527',
}
代理IP可以分为三类
- 透明代理
- 匿名代理
- 高匿代理
关于这三类代理IP分别是什么意思,大家可以自行查阅。
用代理IP访问http://httpbin.org/ip
import requests
proxies = {
'http':'http://117.191.11.112'
}
headers = {
"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"
}
r = requests.get('http://httpbin.org/ip',proxies = proxies,headers = headers)
print(r.text)
还有一些requests模块使用的小技巧,也在最后跟大家分享一下。
设置请求超时时间
我们在爬取网站的时候,可能会遇到网络不是很好的情况下,这时候我们在用requests模块发送请求的时候,可能会等很久都没有结果。这时候我们可以设置一个最长的等待时间,如果超过了就报错。
参数:timeout=3
timeout=3
表示:发送请求后,3秒钟内返回响应,否则就抛出异常
使用也非常的简单
response = requests.get(url,timeout=10)
请求SSL证书验证
我们在访问某些网站的时候,可能会遇到这种情况,如果我们这个时候用requests模块去请求的话,一样是得不到结果的,原因是该网站的CA证书没有经过【受信任的根证书颁发机构】的认证
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kxfPbPDO-1667656829797)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/2f0d1c2cad70450ca0e6ad6093b7a9d4~tplv-k3u1fbpfcp-watermark.image?)]
我们在用requests请求的时候加上参数verify=False
response = requests.get('https://inv-veri.xxxx.gov.cn/',verify=False)