requests高级用法

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-cookieshttp://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()
解决requests向https网站发送请求提示warring的问题

正文内容工作流程

默认情况下,当您发出请求时,会立即下载响应正文。您可以覆盖此行为并推迟下载响应正文,直到您使用参数访问该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

posted @ 2019-03-27 14:48  凌笑丶  阅读(484)  评论(0编辑  收藏  举报