python模块详解 | requests

Requests: 让 HTTP 服务人类

WechatIMG376(已去底) (1)

官方文档 - 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)请求参数

  1. 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'
    
  2. headers

    如果你想为请求添加 HTTP 头部,只要简单地传递一个 dictheaders 参数就可以了。

    url = 'https://api.github.com/some/endpoint'
    headers = {'user-agent': 'my-app/0.0.1'}
    
    r = requests.get(url, headers=headers)
    
  3. 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"
        ]
      },
      ...
    }
    
  4. cookies

  5. 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)响应内容

  1. text - 返回请求响应体的文档树

  2. encoding

    r.encoding返回当前的编码格式,如需修改编码格式:

    r.encoding = 'utf-8'
    
  3. content

    对于非文本请求,你也能以字节的方式访问请求响应体(二进制响应内容),比如图片格式的响应体

    r = requests.get('https://download.chenxuefan.cn/pic/main.png')
    r.content
    
  4. 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() 
    
  5. raw

    在罕见的情况下,你可能想获取来自服务器的原始套接字响应,那么你可以访问 r.raw

    r = requests.get('https://api.github.com/events', stream=True)
    r.raw
    
  6. status_code - 响应状态码

    Requests还附带了一个内置的状态码查询对象requests.codes,其中包含各个状态码,如requests.codes.okrequests.codes.okay表示请求成功,状态码为200

    r = 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()
    

    image-20210506164931511

  7. headers - 响应头

    r.headers返回字典类型的服务器响应头,还比较特殊:它是仅为 HTTP 头部而生的。根据 RFC 2616, HTTP 头部是大小写不敏感的。

    因此,我们可以使用任意大写形式来访问这些响应头字段:

    >>> r.headers['Content-Type']
    'application/json'
    
    >>> r.headers.get('content-type')
    'application/json'
    
  8. 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 ) 进行迭代。简单地设置 streamTrue 便可以使用 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'
}


1683 字