Session对象具有主Requests API的所有方法。
Session对象可以在请求中保留一些cookie:
s = requests.Session() # 会保留cookie s.get('https://httpbin.org/cookies/set/sessioncookie/123456789') r = s.get('https://httpbin.org/cookies') print(r.text) # '{"cookies": {"sessioncookie": "123456789"}}'
Session还可用于向请求方法提供默认数据。这是通过向Session对象上的属性提供数据来完成的,传递给请求方法的任何字典都将与设置的会话级值合并。方法级参数覆盖会话参数。
s = requests.Session() s.headers.update({'x-test': 'true'}) s.get('https://httpbin.org/headers', headers={'x-test2': 'true'})
但请注意,即使使用会话,方法级参数也不会在请求之间保持不变。此示例仅发送带有第一个请求的cookie,但不发送第二个请求:
s = requests.Session() r = s.get('https://httpbin.org/cookies', cookies={'from-my': 'browser'}) print(r.text) # '{"cookies": {"from-my": "browser"}}' r = s.get('https://httpbin.org/cookies') print(r.text) # '{"cookies": {}}'
如果要手动将cookie添加到会话中,请参考:http://docs.python-requests.org/en/latest/api/#api-cookies及http://docs.python-requests.org/en/latest/api/#requests.Session.cookies
cookie_dict = {'x-text': 'true'} # 构建cookiejar对象 cookies = requests.utils.cookiejar_from_dict(cookie_dict, cookiejar=None, overwrite=True) # 可以使用上下文管理器打开会话 with requests.Session() as s: s.cookies = cookies re = s.get('https://httpbin.org/cookies') print(re.text) r = s.get('https://httpbin.org/cookies') print(r.text) s.close()
请求和响应对象
# 获取响应头信息 response.headers # 获取请求头信息 response.request.headers
SSL证书验证
请求验证HTTPS请求的SSL证书,就像Web浏览器一样。默认情况下,启用SSL验证,如果无法验证证书,则Requests将抛出SSLError:
# 此域没有设置SSL,因此会引发异常 >>> requests.get('https://requestb.in') requests.exceptions.SSLError: hostname 'requestb.in' doesn't match either of '*.herokuapp.com', 'herokuapp.com'
您可以将verify
路径传递给具有受信任CA证书的CA_BUNDLE文件或目录:
# 不持久的设置 requests.get('https://github.com', verify='/path/to/certfile') # 持久的设置 s = requests.Session() s.verify = '/path/to/certfile'
如果设置verify
为False,请求也可以忽略验证SSL证书:
requests.get('https://kennethreitz.org', verify=False) <Response [200]>
# 注意依然需要设置 verify=False 来忽略证书的验证 requests.packages.urllib3.disable_warnings()
正文内容工作流程
默认情况下,当您发出请求时,会立即下载响应正文。您可以覆盖此行为并推迟下载响应正文,直到您使用参数访问该Response.content
属性stream,此时只下载了响应头并且连接保持打开状态,因此允许我们以有条件的方式进行内容检索:
if int(response.headers['content-length']) < TOO_LONG: content = r.content ...
您可以使用Response.iter_content()
和Response.iter_lines()
方法进一步控制工作流程。另外,您也可以从底层urllib3读取未解码的urllib3.HTTPResponse
的 Response.raw。
流媒体上传
请求支持流式上传,允许您发送大型流或文件而无需将其读入内存。要进行流式传输和上传,只需为您的body提供类似文件的对象:
# 如果以文本模式打开文件,可能会出现错误 with open('massive-body', 'rb') as f: requests.post('http://some.url/streamed', data=f)
请求还支持以生成器的形式上传内容
def gen(): yield 'hi' yield 'there' requests.post('http://some.url/chunked', data=gen())
链接标题
许多HTTP API都具有链接头。它们使API更具自我描述性和可发现性。例如:
url = 'https://api.github.com/users/kennethreitz/repos?page=1&per_page=10' r = requests.head(url=url) r.headers['link'] '<https://api.github.com/users/kennethreitz/repos?page=2&per_page=10>; rel ="next", <https://api.github.com/users/kennethreitz/repos?page=6&per_page=10>; rel="last"'
请求将自动解析这些链接标头并使其易于使用:
r.links["next"] {'url': 'https://api.github.com/users/kennethreitz/repos?page=2&per_page=10', 'rel': 'next'} r.links["last"] {'url': 'https://api.github.com/users/kennethreitz/repos?page=7&per_page=10', 'rel': 'last'}
超时
如果服务器没有及时响应,大多数对外部服务器的请求都应附加超时。默认情况下,除非明确设置超时值,否则请求不会超时。没有超时,您的代码可能会挂起几分钟或更长时间。
# 指定超时时间 r = requests.get('https://github.com', timeout=5) # 指定连接和读取超时时间 r = requests.get('https://github.com', timeout=(3.05, 27)) # 如果远程服务器响应特别慢,可以设置为None永远等待响应 r = requests.get('https://github.com', timeout=None)
更多请参考官方文档:http://docs.python-requests.org/en/latest/user/advanced/#advanced