会话对象
跨请求保持某些参数
例如cookie
1
2
3
4
5
6
7s = requests.Session()
s.get('http://httpbin.org/cookies/set/sessioncookie/123456789')
r = s.get("http://httpbin.org/cookies")
print(r.text)
# '{"cookies": {"sessioncookie": "123456789"}}'会话对象的属性提供(保持的)数据
1
2
3
4
5
6s = requests.Session()
s.auth = ('user', 'pass')
s.headers.update({'x-test': 'true'})
# both 'x-test' and 'x-test2' are sent
s.get('http://httpbin.org/headers', headers={'x-test2': 'true'})请求方法级别的参数也不会被跨请求保持
手动为会话添加 cookie,就使用 Cookie utility 函数 来操纵 Session.cookies。
若想省略会话中的某些参数,通过在方法层参数中将那个键的值设置为 None
会话前后文管理器,自动关闭会话
1
2with requests.Session() as s:
s.get('http://httpbin.org/cookies/set/sessioncookie/123456789')
PreparedRequest 对象
介绍:发送请求之前,你需要对 body 或者 header (或者别的什么东西)做一些额外处理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23from requests import Request, Session
s = Session()
req = Request('GET', url,
data=data,
headers=header
)
prepped = req.prepare() # 无法进行 Session 级别的状态保持
prepped = s.prepare_request(req) #可以
# do something with prepped.body
# do something with prepped.headers
resp = s.send(prepped,
stream=stream,
verify=verify,
proxies=proxies,
cert=cert,
timeout=timeout
)
print(resp.status_code)
SSL 证书验证
- 默认情况下,请求方法含参数verify=True
客户端证书
CA证书
响应体内容工作流
- 使用
1
2
3
4
5
6with requests.get('http://httpbin.org/get', stream=True) as r:
pass
# 根据条件获取(部分或全部)内容
if int(r.headers['content-length']) < TOO_LONG:
content = r.content
... - 在请求中把 stream 设为 True,Requests 无法将连接释放回连接池,除非你 消耗了所有的数据,或者调用了 Response.close。
- 使用
保持长连接
- 同一会话内的持久连接是完全自动处理的。
- 只有所有的响应体数据被读取完毕连接才会被释放为连接池;所以确保将 stream 设置为 False 或读取 Response 对象的 content 属性。
流式上传(文件,图片啥的)
好处是:数据流或文件而无需先把它们读入内存,记得以二进制读取
1
2with open('massive-body') as f:
requests.post('http://some.url/streamed', data=f)
POST 多个分块编码的文件(发送多个文件)
要上传多个图像文件到一个 HTML 表单
1
<input type="file" name="images" multiple="true" required="true"/>
把文件设到一个元组的列表中
1
2
3
4
5
6
7
8
9
10
11
12url = 'http://httpbin.org/post'
multiple_files = [
('images', ('foo.png', open('foo.png', 'rb'), 'image/png')),
('images', ('bar.png', open('bar.png', 'rb'), 'image/png'))]
r = requests.post(url, files=multiple_files)
r.text
{
...
'files': {'images': 'data:image/png;base64,iVBORw ....'}
'Content-Type': 'multipart/form-data; boundary=3131623adb2043caaeb5538cc7aa0b3a',
...
}
可用的钩子:response
传递一个 {hook_name: callback_function} 字典给 hooks 请求参数为每个请求分配一个钩子函数。
1
2
3
4
5
6def print_url(r, *args, **kwargs):
print(r.url)
requests.get('http://httpbin.org', hooks=dict(response=print_url))
http://httpbin.org
<Response [200]>
自定义身份认证
自定义的身份验证机制是作为 requests.auth.AuthBase 的子类来实现的。
提供了两种常见的的身份验证方案: HTTPBasicAuth 和 HTTPDigestAuth 。
假设我们有一个web服务,仅在 X-Pizza 头被设置为一个密码值的情况下才会有响应。虽然这不太可能,但就以它为例好了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15from requests.auth import AuthBase
class PizzaAuth(AuthBase):
"""Attaches HTTP Pizza Authentication to the given Request object."""
def __init__(self, username):
# setup any auth-related data here
self.username = username
def __call__(self, r):
# modify and return the request
r.headers['X-Pizza'] = self.username
return r
requests.get('http://pizzabin.org/admin', auth=PizzaAuth('kenneth'))
<Response [200]>
流式请求(即请求含有stream=True参数)
对返回数据可进行迭代
1
2
3
4
5
6
7
8
9r = requests.get('http://httpbin.org/stream/20', stream=True)
# 注意要有回退编码,若且默认情况没有会报错
if r.encoding is None:
r.encoding = 'utf-8'
for line in r.iter_lines(decode_unicode=True):
if line:
print(json.loads(line))
代理(请求中使用proxies={key:value}参数)
SOCKS 协议的代理,同上,但value有所不同
HTTP动词
查看某一端口的限制次数
1
2
3
4
5
6
7r = requests.head(url=url, auth=auth)
print r.headers
...
'x-ratelimit-remaining': '4995'
'x-ratelimit-limit': '5000'
...
# 结果显示:可以使用 4995 次,一共5000次。
·········