更新日期: 2021.04.11
本节学习内容 :掌握 requests 库的常用方法。
目录
1. requests库可以做什么?
requests库使HTTP为人类服务~
提供全方位的支持 - 帮助我们自动化地获取静态网页的信息。
2. 学习资料来源(官网最新版本)
打开www.python.org,找到第三方库中的requests,注意屏幕右上方的 “Latest version" 是绿色的,确保导入和学习的都是当前最新版本:requests 2.25.1 (Released on Dec 17, 2020)
然后,通过这个页面找到学习的入口,先看 Quick Start 部分。
https://requests.readthedocs.io/en/master/user/quickstart/
3. GET请求可以做什么?
get请求是requests库最常用的功能,用来完成获取网页信息的绝大部分操作。
4. GET请求 - 必备参数
4.1 url - 目标网址
为了获取一个网页的内容,把 url 作为参数提交给 get 语句获得 r 这个object。
同时,获得了 r 的相关信息,如 text, content 等,后面再一一介绍。
import requests
r = requests.get("https://api.github.com/events")
4.2 headers (请求头) - 表明身份
在请求网页信息时, 如果不提交 headers 很可能会被服务器认定为爬虫而限制访问,或者在访问频率较高时被禁止访问。所以,应添加请求头,表明身份。
请求头的含义及怎样查找自己的请求头, 参见前一节。
Python爬虫学习 - 从零开始 2 (初识 requests + bs4 + re)
4.3 timeout - 设置运行超期时间限制
设置超期时间限制, 避免网站没有响应时程序还在无限期的等待。
如果仅设置一个时间, connect 和 read 都使用这个时间限制。
如果设置了两个时间, 前一个代表连接超时控制, 一般设为比3秒的整数倍稍长一点 (默认值为21秒), 后一个代表读取超时控制 (默认值为无穷大…)
requests.get('https://github.com/', timeout=2)
requests.get('https://github.com/', timeout=3.05, 27)
5. GET请求 - 选配参数
5.1 params - 提交参数以获得需要的信息
import requests
data = {
'name': 'Guess',
'interest': ['badminton', 'keepfit']
}
r = requests.get('https://httpbin.org/get', params=data)
print(r.url) # https://httpbin.org/get?name=Guess&interest=badminton&interest=keepfit
5.2 verify - 是否进行SSL证书审核
get 请求默认审核 https 网站的SSL证书, 并阻止访问没有证书的网站。
在请求中加入"verify=False" 将不再查看证书。
requests.get('https://kennethreitz.org', verify=False)
5.3 cookies - 使用账号登录网页
cookies 用于需要登录才能访问的网页, 以便于持续获取数据。
r = requests.get('http://news.baidu.com/')
print(r.cookies) # <RequestsCookieJar[<Cookie BAIDUID=891D8FXXXX:FG=1 for .baidu.com/>]>
# 如同时获得了多个cookies, 可以使用名字获得相应的值
#r.cookies['example_cookie_name'] # 'example_cookie_value'
# 自己设置cookies放在get请求里
# r = requests.get(url, cookies=my_cookies)
5.4 allow_redirects - 禁止网页跳转至新网址
默认情况下, 如果网站进行了设置,获取网页的请求会被服务器自动定位到新网址。
例如访问GitHub时由 http 转向 https,可在提交请求时禁止网页重新定位。
r = requests.get('http://github.com/', allow_redirects=False)
print(r.status_code) # 301,表示此网页已经永久性转至新网址
r = requests.get('http://github.com/')
print(r.url) # 'https://github.com/' # url自动转换为新网址
print(r.status_code) # 200
print(r.history) # [<Response [301]>]
5.5 其它选配参数(比如设置代理),感觉现阶段用不上,先不看啦~
6. POST请求
基本使用方法和 get 一样。
查看 network/ XHR选项卡,如页面信息是由 post 请求获得的,就构造相应的请求获取信息。
- URL使用 post 上方的 Request URL
- 参数使用这个请求最下方的 From data的信息(见下图2)
- 注意,post 请求中的参数关键字是 data (等同于get 中的 params 参数)。
7. 使用 get/ post 方法可以获取什么?
7.1 页面信息 r.text & r.content
7.1.1 r.text (普通类型)
r.text 返回 str类型(Unicode编码)。requests模块基于网页响应的文本推测网页代码的编码规则, 然后使用相应的解码规则解码 。
大多数unicode字符集都可以被正确的解码。不过,如果猜错了,就会返回乱码。🙈🙈
7.1.2 r.text (中文乱码)
有时处理中文信息时会得到乱码, 主要是因为编码解码方式不同造成的, 可以分别尝试使用以下两种方法。
response = requests.get(url, hearders)
# 手动设定响应数据的编码格式
response.encoding = "utf-8"
text = response.text
# 对需获取的目标信息按照以下方式进行编码解码
img_name = li.Xpath('.//a/@alt')[0] + 'jpg'
img_name = img_name.encode('iso-8859-1').decode('gbk')
7.1.3 r.content (二进制字节流)
r.content 返回的是服务器响应的原始二进制字节流, 可以用来保存图片等二进制文件。
对于包含了图片,视频等二进制字节流的网页部分,直接打印效果如下。
r = requests.get("http://img02.tuke88.com/preview/2269348/00/01/12/5b1a0bfd16566.jpg-0.jpg!/fw/340")
print(type(r)) # <class 'requests.models.Response'>
print(r.text)
print(r.content)
print(r.text) :
print(r.content)
获得图片信息的 content后, 以 wb (二进制写入) 存为 jpg 文件。
response = requests.get("http://img02.tuke88.com/preview/2269348/00/01/12/5b1a0bfd16566.jpg-0.jpg!/fw/340")
img_data = response.content
with open('./target_img.jpg', 'wb') as fp:
fp.write(img_data)
7.2 其他形式的网页信息
7.2.1 JSON格式 - 可直接获取目标信息(不用下载全部网页)
打开 Headers 选项卡,在Response Headers 部分查看 Content- Type。
如果信息为JSON格式,import JSON 库处理。
import requests
import json
r = requests.get('https://api.github.com/events')
my_data = r.json() # [{u'repository': {u'open_issues': 0, u'url': 'https://github.com/...
fp = open('./my_data.json', 'w', encoding = "utf-8")
json.dump(my_data, fp = fp, ensure_ascii = False)
7.2.2 raw 格式
如需要可以通过如下方式获得, 一般不需要…
r = requests.get('https://api.github.com/events', stream=True)
print(r.raw) # <urllib3.response.HTTPResponse object at 0x101194810>
print(r.raw.read(10)) #'\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03'
7.3 其它信息 - headers等
其它信息的查看,略~
r = requests.get('http://news.baidu.com/')
print(r.headers)
print(r.headers['Content-Type']) # text/html;charset=utf-8
print(r.headers.get('content-type')) # text/html;charset=utf-8
print(r.encoding) # 从headers部分分析/猜测得到的编码方式
print(r.apparent_encoding) # 从body部分分析/猜测得到的编码方式
8. 使用 Session 保持和服务器的联系
在提交信息登录网站后,接下来的访问中可能还会被要求再次登录,这是因为服务器并不知道这个新请求是由一个已经登录的用户提交的。
把第一次登录后获得的 cookies 通过参数形式提交给 Session 后 (提交一次), Session 将在之后的登录中携带此信息,并根据网站更新的cookies随时更新自身的cookies信息。
# 初始化 session 对象
session = requests.Session()
# 把 get 或 post 语句中的 requests 替换成 session
response = session.get(url, headers, params/data).text
9. 注意事项
9.1 响应状态代码 - 是200吗?
正常的代码只有200一个, 还有很多其他代码, 以3或4开头的, 都是不正常的状态。
可以直接查看代码是不是==200, 以确认是否继续执行程序。也可以使用requests 库自带的检测方式。其它状态代码暂时不需关注, 需要时再查看解决方法。
r = requests.get('https://httpbin.org/get')
print(r.status_code) # 200
r.status_code == requests.codes.ok # True
9.2 异常处理
不论服务器, 网络, 还是本地账号等发生异常, 或者超时, 系统都会报错并停止运行。
可以使用requests.exceptions.RequestException 捕获所有异常。使用方法参见前一节。
9.3 sleep - 避免被拉黑
不要高频爬取同一个网站,可能会影响人家的正常运营,也避免自己被拉黑~
使用方法参见前一节,一般可设为1秒。
10. 总结
- requests 功能强大,使用方便,是人类的好助手~~~
- 其中 get 方法的必备参数设置,注意事项,以及 .text .content 的使用需熟练掌握。
- 其他方法/功能大致了解下,需要时再学。