python模块详解 | requests
Requests: 让 HTTP 服务人类
官方文档 - https://docs.python-requests.org/zh_CN/latest/
快速上手
https://docs.python-requests.org/zh_CN/latest/user/quickstart.html
(1)发送请求
request(method, url, **kwargs)
get(url, params=None, **kwargs)
options(url, **kwargs)
head(url, **kwargs)
post(url, data=None, json=None, **kwargs)
put(url, data=None, **kwargs)
patch(url, data=None, **kwargs)
delete(url, **kwargs)
r = requests.put('http://httpbin.org/put', data = {'key':'value'})
r = requests.delete('http://httpbin.org/delete')
r = requests.head('http://httpbin.org/get')
r = requests.options('http://httpbin.org/get')
(2)请求参数
-
params
发送get请求时,若想在不修改URL的内容的情况下添加URL参数,可将params参数添加到请求之中。
params = {'key':'value'} r = requests.get('http://httpbin.org/get', params=params)
r.url
打印得到此时的URL:Out[4]: 'http://httpbin.org/get?key=value'
-
headers
如果你想为请求添加 HTTP 头部,只要简单地传递一个
dict
给headers
参数就可以了。url = 'https://api.github.com/some/endpoint' headers = {'user-agent': 'my-app/0.0.1'} r = requests.get(url, headers=headers)
-
data
通常,你想要发送一些编码为表单形式的数据——非常像一个 HTML 表单。要实现这个,只需简单地传递一个「字典」给 data 参数。你的数据字典在发出请求时会自动编码为表单形式:
data = {'key1': 'value1', 'key2': 'value2'} r = requests.post('http://httpbin.org/post',data=data)
除了传递一个字典,还可以传递一个「元祖列表」给data参数。在表单中多个元素使用同一 key 的时候,这种方式尤其有效:
>>> payload = (('key1', 'value1'), ('key1', 'value2')) >>> r = requests.post('http://httpbin.org/post', data=payload) >>> print(r.text) { ... "form": { "key1": [ "value1", "value2" ] }, ... }
-
cookies
-
timeout
你可以告诉 requests 在经过以
timeout
参数设定的秒数时间之后停止等待响应。基本上所有的生产代码都应该使用这一参数。如果不使用,你的程序可能会永远失去响应:requests.get('http://github.com', timeout=0.001)
timeout
仅对连接过程有效,与响应体的下载无关。timeout
并不是整个下载响应的时间限制,而是如果服务器在timeout
秒内没有应答,将会引发一个异常(更精确地说,是在timeout
秒内没有从基础套接字上接收到任何字节的数据时)If no timeout is specified explicitly, requests do not time out.
(3)响应内容
-
text - 返回请求响应体的文档树
-
encoding
r.encoding
返回当前的编码格式,如需修改编码格式:r.encoding = 'utf-8'
-
content
对于非文本请求,你也能以字节的方式访问请求响应体(二进制响应内容),比如图片格式的响应体
r = requests.get('https://download.chenxuefan.cn/pic/main.png') r.content
-
json()
如果 JSON 解码失败,
r.json()
就会抛出一个异常:ValueError: No JSON object could be decoded
。需要注意的是,成功调用r.json()
并不意味着响应的成功。r = requests.get('https://download.chenxuefan.cn/pic/main.png') r.json()
-
raw
在罕见的情况下,你可能想获取来自服务器的原始套接字响应,那么你可以访问
r.raw
。r = requests.get('https://api.github.com/events', stream=True) r.raw
-
status_code - 响应状态码
Requests还附带了一个内置的状态码查询对象
requests.codes
,其中包含各个状态码,如requests.codes.ok
或requests.codes.okay
表示请求成功,状态码为200r = requests.get('http://httpbin.org/get') if r.status_code == requests.codes.ok: continue
如果发送了一个错误请求(一个 4XX 客户端错误,或者 5XX 服务器错误响应),我们可以通过
Response.raise_for_status()
来抛出异常:if r.status_code != 200: r.raise_for_status()
-
headers - 响应头
r.headers
返回字典类型的服务器响应头,还比较特殊:它是仅为 HTTP 头部而生的。根据 RFC 2616, HTTP 头部是大小写不敏感的。因此,我们可以使用任意大写形式来访问这些响应头字段:
>>> r.headers['Content-Type'] 'application/json' >>> r.headers.get('content-type') 'application/json'
-
cookies
Cookie 的返回对象为
RequestsCookieJar
,它的行为和字典类似,但接口更为完整,适合跨域名跨路径使用。>>> url = 'http://example.com/some/cookie/setting/url' >>> r = requests.get(url) >>> r.cookies Out[29]: <RequestsCookieJar[]>
高级用法
https://docs.python-requests.org/zh_CN/latest/user/advanced.html#advanced
(1)会话对象
会话对象让你能够跨请求保持某些参数。它也会在同一个 Session 实例发出的所有请求之间保持 cookie。
session = requests.Session()
r = session.get(url)
会话也可用来为请求方法提供缺省数据。这是通过为会话对象的属性提供数据来实现的:
s = requests.Session()
s.auth = ('user', 'pass')
s.headers.update({'x-test': 'true'})
会话还可以用作前后文管理器:
with requests.Session() as s:
s.get('https://chenxuefan.cn')
这样就能确保with区块退出后回话能被关闭,即使发生了异常也一样。
(2)SSL证书验证
Requests 可以为 HTTPS 请求验证 SSL 证书,就像 web 浏览器一样。SSL 验证默认是开启的,如果证书验证失败,Requests 会抛出 SSLError:
requests.get('https://github.com', verify=True)
(3)客户端证书
你也可以指定一个本地证书用作客户端证书,可以是单个文件(包含密钥和证书)或一个包含两个文件路径的元组:
requests.get('https://kennethreitz.org', cert=('/path/client.cert', '/path/client.key'))
(4)流式上传
Requests支持流式上传,这允许你发送大的数据流或文件而无需先把它们读入内存。要使用流式上传,仅需为你的请求体提供一个类文件对象即可:
with open('massive-body') as f:
requests.post('http://some.url/streamed', data=f)
(5)流式请求
使用 Response.iter_lines()
你可以很方便地对流式 API (例如 Twitter 的流式 API ) 进行迭代。简单地设置 stream
为 True
便可以使用 iter_lines
对相应进行迭代:
import json
import requests
r = requests.get('http://httpbin.org/stream/20', stream=True)
for line in r.iter_lines():
# filter out keep-alive new lines
if line:
decoded_line = line.decode('utf-8')
print(json.loads(decoded_line))
(6)代理
如果需要使用代理,你可以通过为任意请求方法提供 proxies
参数来配置单个请求:
import requests
proxies = {
"http": "http://10.10.1.10:3128",
"https": "http://10.10.1.10:1080",
}
requests.get("http://example.org", proxies=proxies)
(7)SOCKS
除了基本的 HTTP 代理,Request 还支持 SOCKS 协议的代理。这是一个可选功能,若要使用, 你需要安装第三方库。
你可以用 pip
获取依赖:
$ pip install requests[socks]
安装好依赖以后,使用 SOCKS 代理和使用 HTTP 代理一样简单:
proxies = {
'http': 'socks5://user:pass@host:port',
'https': 'socks5://user:pass@host:port'
}