requests库(二)

  • 会话对象

    • 跨请求保持某些参数

      例如cookie

      1
      2
      3
      4
      5
      6
      7
      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"}}'
    • 会话对象的属性提供(保持的)数据

      1
      2
      3
      4
      5
      6
      s = 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
      2
      with 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
      23
      from 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
      6
      with 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
      2
      with 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
      12
      >>> url = '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
      6
      def 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
      15
      from 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
      9
      r = 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
      7
      >>> r = requests.head(url=url, auth=auth)
      >>> print r.headers
      ...
      'x-ratelimit-remaining': '4995'
      'x-ratelimit-limit': '5000'
      ...
      # 结果显示:可以使用 4995 次,一共5000次。

·········