这是日常学 python 的第 11 篇原创文章
在使用了 urllib 库之后, 感觉很麻烦, 比如获取个 cookie 都需要分几步, 代码又多, 这和 python 的风格好像有点不太像哈, 那有没有更加容易点的请求库呢? 答案是有的, 那就是第三方库 requests, 这个库的作者是大名鼎鼎的 kennethreitz, 创作这个库的原因就是想让 python 开发者更加容易地发起请求, 处理请求里面还有个名字: HTTP for Humans, 顾名思义, 就是用来请求 http 的想看源代码的可以在 github 上搜索他的名字就可以看到了
接下来介绍下怎样用这个库吧!
(这文章原创首发于公众号 [日常学 python] )
因为这是第三方库, 所以我们需要下载, 需要在命令行输入
pip install requests
如果你装的是 anacoda 可以忽略这条
安装好了就来进行使用吧
1
进行简单的操作
发送一个 get 请求
- # 发送请求
- import requests
- response = requests.get('http://httpbin.org/get')
- # 获取返回的 html 信息
- print(response.text)
这样就发送了一个 get 请求, 并且还打印了返回的内容, 这个不再需要知道网页是哪个编码的, 不过有时会出现编码问题, 但是你也可以指定编码类型, 如:
response.encoding = 'utf-8'
指定完成后就可以正常编码了, 前提你得知道网页的编码类型
出了上面这些, 我们还可以获取下面的信息
- print(response.headers)
- # 请求状态码
- print(response.status_code)
- # 获取网页的二进制内容
- print(response.content)
- print(response.url) # 获取请求的 url
- print(response.cookies) # 获取 cookie
是不是觉得很容易, 一行代码就可以了不再需要几步代码什么的了
接下来被发爬的话带上个请求头来进行请求
- # 还可以添加请求头进行请求
- headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) ApplewebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36'}
- response = requests.get('httpbin.org/get', headers=headers )
- print(response.headers)
- print(response.text)
加个请求头也就是加个关键字参数而已
还可以进行带参数的 get 请求
- # 进行带参数的 get 请求
- data = {'name': 'june', 'password': 123456}
- response = requests.get('http://httpbin.org/get', params=data)
- print(response.text)
那如果需要登陆呢? post 请求怎样发? 告诉你, 照样很简单
- # 进行 post 请求
- data = {'name': 'june', 'password': 123456}
- response = requests.post('http://httpbin.org/post', data=data, headers=headers)
- print(response.text)
是不是很简单, 也是加个 data 关键字参数, 把要提交的登陆参数进行 post 上去
那除了上面的两个请求, 还能进行别的请求吗? 我可以非常开心地告诉你, 可以的比如, 你要发个 put 请求, 如这样
- requests.put()
- requests.delete()
这个就是发送 put 请求和 delete 请求的, 其他的请求也是这样发送, 就不一 一说了
2
进行复杂点的请求
在登陆的时候我们有时候需要输入验证码, 那怎样输呢? 爬虫的看不了网页, 最简单的做法就是把这个验证码的图片下载下来然后手动输入, 那么我们怎样下载呢? 我们可以向这个图片的 url 发送请求, 然后把返回内容以二进制方法存入文件里面就可以了
代码如下:
- # 从网上读取二进制数据, 比如图片
- response = requests.get('https://www.baidu.com/img/bd_logo1.png', headers=headers)
- # 这个是直接获取字节码, 这个是要保存的文件
- print(response.content)
- # 这个是获取解码后的返回内容, 这个是乱码
- print(response.text)
- # 用文件来把图片下载下来
- with open('baidu.png', 'wb') as f: # 注意写的方式是以二进制方式写入
- f.write(response.content)
- print('下载完毕')
还是很简单, 不得不说, 这个库太好用了
当我们需要上传文件的时候, 比如图片, 我们还可以用 post 方法把他发送出去
- # 上传文件
- files = {'picture': open('baidu.png', 'rb')}
- response = requests.post('http://httpbin.org/post', files=files)
- print(response.text)
获取 cookie 并简单处理一下
- # 获取 cookie
- response = requests.get('https://www.baidu.com')
- for k, v in response.cookies.items():
- print(k, '=', v)
当网页返回内容是 json 格式是, 我们不需要用 json 库来解析, 我们可以直接利用 requests 的方法进行解析, 两者的效果是一样的
- # 解析 json
- j = response.json() # 可以用 json 库来解析, 结果一样
在 urllib 库时保存登陆信息需要把 cookie 保存下来, 但是在 requests 库里面, 我们只需要用 requests.session() 来保存信息就可以了
- # 用会话来保持登陆信息
- session = requests.session()
- response = session.get('http://httpbin.org/cookies/set/number/123456')
- print(response.text)
这样就可以保存登陆了, 不需要为 cookie 操心了, 但是每次获取一个 session 就可以了, 然后用来请求或者其他操作不需要每次请求或者操作都创建一个 sesion 出来, 这样是保存不了登陆信息的
当一个网站不安全, 需要你用证书验证的, 比如这个网站
https://www.12306.cn
这时要访问里面的网站内容, 我们就需要进行验证, 代码如下
- # 证书验证
- response = requests.get('https://www.12306.cn', verify=False) # 不加这个关键字参数的话会出现验证错误问题, 因为这个网站的协议不被信任
这样就可以进行访问了, 但是会有一条警告
- E:\anaconda\lib\site-packages\urllib3\connectionpool.py:858: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
- InsecureRequestWarning)
觉得不美观的, 我们还可以在请求时加个 cert 关键字参数, 值为可信任的证书, 为一个元组, 写上账号和密码之类的, 这里就不演示了
遇到需要认证的网站, 我们也可以这样
- from requests.auth import HTTPBasicAuth
- # 设置认证
- # requests.get('需要认证的网址', auth=HTTPBasicAuth('user', 'passwd')) # 由于找不到需要认证的网址, 所以先写个主体
- # 还可以这样认证
- # requests.get('需要认证的网址', auth=('user', 'passwd')) # 这样就简单点
由于我找不到需要认证的网站, 所以就不演示了
requests 还可以用代理 ip 来进行请求网站来防止 ip 被封以至于自己爬不了的尴尬使用代理 ip 也比 urllib 库简单得多, 代码如下:
- # 设置代理
- proxies = {'http': 'http://122.114.31.177:808',
- 'https': 'https://119.28.223.103:8088'}
- # 在请求时添加上列代理
- response = requests.get('http://httpbin.org/get', proxies=proxies)
- print(response.text)
上面的字典格式需要一 一对应, 然后在请求时加上个关键字参数 proxies 就可以了
3
请求异常处理
在程序运行时, 遇到错误时程序就会被强行停止, 如果想要继续运行, 就需要进行捕捉异常来让程序继续运行
在 requests 库中有个处理异常的库 requests.exceptions
这里简单地处理下请求超时的处理情况
- import requests
- from requests.exceptions import ReadTimeout, ConnectTimeout, HTTPError, ConnectionError, RequestException
- # 捕捉异常
- try:
- response = requests.get('http://httpbin.org/get', timeout=0.1) # 规定时间内未响应就抛出异常
- print(response.text)
- except ReadTimeout as e:
- print('请求超时')
- except ConnectionError as e:
- print('连接失败')
- except RequestException as e:
- print('请求失败')
这里捕捉了三个异常, 因为 ReadTimeout 是 ConnectionError 的子类, 所以先捕捉 ReadTimeout, 再捕捉父类的而 ConnectionError 和 RequestException 同理
更多的异常处理可以查看文档哈
4
最后
以上均是我在学习时的笔记和个人在运用时遇到的一些坑都简单地记载了上去, 希望对你有用哈, 如果想看更多的用法可以去官方文档查看还有代码我放在了 github 上, 要的话可以上去查看
GitHub:github.com/SergioJune/
官方文档: docs.python-requests.org/zh_CN/lates
学习参考资料: https://edu.hellobi.com/course/157
来源: https://juejin.im/post/5aa7a3246fb9a028be35abbd