三、Requests库的使用
requests 的底层实现其实就是 urllib3
Requests 唯一的一个非转基因的 Python HTTP 库,人类可以安全享用。
学过关于urllib库的使用,你会发现它是很不方便的。而Requests工作起来会比urllib方便,Requests是Python实现的最简单易用的HTTP库,需要通过pip单独安装
开源地址:https://github.com/kennethreitz/requests
中文文档 API: http://docs.python-requests.org/zh_CN/latest/index.html
功能特性
Requests 完全满足今日 web 的需求。
Keep-Alive & 连接池
国际化域名和 URL
带持久 Cookie 的会话
浏览器式的 SSL 认证
自动内容解码
基本/摘要式的身份认证
优雅的 key/value Cookie
自动解压
Unicode 响应体
HTTP(S) 代理支持
文件分块上传
流下载
连接超时
分块请求
支持
.netrc
Requests的演示:
import requests
#注意字典里值为None
的键都不会被添加到 URL 的查询字符串里。
#kw = {'key1': 'value1', 'key2': ['value2', 'value3']}还可以将一个列表传入
kw = {'wd':'jians'} headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"} # params 接收一个字典或者字符串的查询参数,字典类型自动转换为url编码,不需要urlencode() response = requests.get("http://www.baidu.com/s?", params=kw, headers = headers) #<class 'requests.models.Response'> print(type(response)) #<RequestsCookieJar[<Cookie BDORZ=27315 for .baidu.com/>]> print(response.cookies) #200 print(response.status_code) # 查看响应内容,response.text 返回的是Unicode格式的数据 print(response.text) #<class 'str'> print(type(response.text)) # 查看响应内容,response.content返回的字节流数据 print(type(response.content)) #<class 'bytes'> print(response.content) #字节——字符串 print(response.content.decode('utf8')) # 查看响应头部字符编码 print(response.encoding) # response.encoding = 'utf-8'
比urllib方便太多
# params 接收一个字典或者字符串的查询参数,字典类型自动转换为url编码,不需要urlencode()
response = requests.get("http://www.baidu.com/s?", params=kw, headers = headers)
你也许经常想为 URL 的查询字符串(query string)传递某种数据。如果你是手工构建 URL,那么数据会以键/值对的形式置于 URL 中,跟在一个问号的后面。例如, httpbin.org/get?key=val
。 Requests 允许你使用 params
关键字参数,以一个字符串字典来提供这些参数。
# 查看响应头部字符编码
print(response.encoding)
response.encoding = 'utf-8'
如果你改变了编码,每当你访问 response.text
,Request 都将会使用 response.encoding
的新值。你可能希望在使用特殊逻辑计算出文本的编码的情况下来修改编码。比如 HTTP 和 XML 自身可以指定编码。这样的话,你应该使用 response.content
来找到编码,然后设置response.encoding
为相应的编码。这样就能使用正确的编码解析 response.text
了。
在你需要的情况下,Requests 也可以使用定制的编码。如果你创建了自己的编码,并使用 codecs
模块进行注册,你就可以轻松地使用这个解码器名称作为 response.encoding
的值, 然后由 Requests 来为你处理编码。
>>> import requests
>>> r = requests.get('https://github.com/timeline.json')
>>> r.json()
[{u'repository': {u'open_issues': 0, u'url': 'https://github.com/...
如果 JSON 解码失败, r.json()
就会抛出一个异常。例如,响应内容是 401 (Unauthorized),尝试访问 r.json()
将会抛出 ValueError: No JSON object could be decoded
异常。
需要注意的是,成功调用 r.json()
并**不**意味着响应的成功。有的服务器会在失败的响应中包含一个 JSON 对象(比如 HTTP 500 的错误细节)。这种 JSON 会被解码返回。要检查请求是否成功,请使用 r.raise_for_status()
或者检查 r.status_code
是否和你的期望相同。
各种请求方式:
import requests r = requests.get('https://github.com/timeline.json') r = requests.post("http://httpbin.org/post") r = requests.put("http://httpbin.org/put") r = requests.delete("http://httpbin.org/delete") r = requests.head("http://httpbin.org/get") r = requests.options("http://httpbin.org/get")
代理(proxies参数)
如果需要使用代理,你可以通过为任意请求方法提供 proxies
参数来配置单个请求:
import requests # 根据协议类型,选择不同的代理 proxies = { "http": "http://12.34.56.79:9527", "https": "http://12.34.56.79:9527", } response = requests.get("http://www.baidu.com", proxies = proxies)
print(response.text)
也可以通过本地环境变量 HTTP_PROXY
和 HTTPS_PROXY
来配置代理:
export HTTP_PROXY="http://12.34.56.79:9527"
export HTTPS_PROXY="https://12.34.56.79:9527"
私密代理验证(特定格式) 和 Web客户端验证(auth 参数)
urllib这里的做法比较复杂,requests只需要一步:
私密代理
import requests # 如果代理需要使用HTTP Basic Auth,可以使用下面这种格式: proxy = { "http": "mr_mao_hacker:sffqry9r@61.158.163.130:16816" } response = requests.get("http://www.baidu.com", proxies = proxy) print(response.text)
web客户端验证
如果是Web客户端验证,需要添加 auth = (账户名, 密码)
import requests auth=('test', '123456') response = requests.get('http://127.0.0.10', auth = auth)
print(response.text)
Cookies
如果一个响应中包含了cookie,那么我们可以利用 cookies参数拿到:
import requests response = requests.get('http://www.baidu.com') #返回cookiejar对象 cookiejar = response.cookies #转为字典 cookiedict = requests.utils.dict_from_cookiejar(cookiejar) print(cookiejar) print(cookiedict)
结果:
<RequestsCookieJar[<Cookie BDORZ=27315 for .baidu.com/>]>
{'BDORZ': '27315'}
会话对象
会话对象让你能够跨请求保持某些参数。它也会在同一个 Session 实例发出的所有请求之间保持 cookie, 期间使用 urllib3
的 connection pooling 功能。所以如果你向同一主机发送多个请求,底层的 TCP 连接将会被重用,从而带来显著的性能提升。 (参见 HTTP persistent connection).
会话对象具有主要的 Requests API 的所有方法。
我们来跨请求保持一些 cookie:
import requests s = requests.Session() s.get('http://httpbin.org/cookies/set/sessioncookie/123456789') r = s.get("http://httpbin.org/cookies") print(r.text)
{ "cookies": { "sessioncookie": "123456789" } }
处理HTTPS请求 SSL证书验证
Requests也可以为HTTPS请求验证SSL证书:
- 要想检查某个主机的SSL证书,你可以使用 verify 参数(也可以不写)
import requests response = requests.get("https://www.baidu.com/", verify=True) # 也可以省略不写 # response = requests.get("https://www.baidu.com/") print(r.text)
- 如果SSL证书验证不通过,或者不信任服务器的安全证书,则会报出SSLError,据说 12306 证书是自己做的.
- 如果我们想跳过 12306 的证书验证,把 verify 设置为 False 就可以正常请求了。虽然可以访问网页但会提示:
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)
解决方法:
import requests import urllib3 urllib3.disable_warnings() r = requests.get("https://www.12306.cn/mormhweb/", verify = False) print(r.text)