一、发送请示
# 导入 Requests 模块 import requests # 获取某个网页 r = requests.get("http://www.baidu.com")
可以发送 HTTP POST、PUT、DELETE、HEAD 以及 OPTIONS 请求:
r = requests.post('http://httpbin.org/post', data = {'key':'value'}) 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')
二、传递 URL 参数
比如 http://httpbin.org/get?key=val传递key=val的参数, 在Request 使用 params 关键字参数,以一个字符串字典来提供这些参数。举例,如想传递 key1=value1 和 key2=value2 到 http://httpbin.org/get ,可以使用如下代码
payload = {'key1':'value1', 'key2':'value2'} r = requests.get("http://httpbin.org/get", params=payload) # 查看打印 URL 地址是否正确 print(r.url) # out: http://httpbin.org/get?key2=value2&key1=value1
注意:字典里值为 None 的键不会被添加到 URL 的查询字符串里。
还可以将一个列表作为值传入,例如下:
payload = {'key1': 'value1', 'key2': ['value2', 'value3']} r = requests.get(('http://httpbin.org/get', params=payload) print(r.url) # out: http://httpbin.org/get?key1=value1&key2=value2&key2=value3
三、响应内容
读取服务器响应的内容。例如下:
# 导入 Requests 模块 import requests # 获取某个网页 r = requests.get("https://api.github.com/events") # 获取服务器响应内容 print(r.text) # out: u'[{"repository":{"open_issues":0,"url":"https://github.com/...
使用 r.encoding = "ISO-8859-1" 修改文本编码格式,显示改变编码后的响应内容。如果你想在使用特殊逻辑计算出文本的编码的情况下来修改编码,应该使用 r.content 来找到编码,然后设置 r.conding 为相应的编码。这样就能使用正确的编码解析 r.text 了。在学习codecs模块后,可以使用定制的编码。
四、二进制响应内容
你能以字节的方式访问请求响应体,对于非文本请求:
>>> c.content b'[{"repository":{"open_issues":0,"url":"https://github.com/...
Requests 会自动为你解码 gzip 和 deflate 传输编码的响应数据。
例如,以请求返回的二进制数据创建一张图片,你可以使用如下代码:
>>> from PIL import Image >>> from io import BytesIO >>> i = Image.open(BytesIO(r.content))
四、JSON响应内容
Requests 中也有一个内置的 JSON 解码器,助力处理 JSON 数据:
>>> import requests >>> r = requests.get('https://api.github.com/events') >>> r.json() [{u'repository': {u'open_issues': 0, u'url': 'https://github.com/...
如果JSON解码失败, r.json() 就会抛出一个异常。例如,响应内容是 401 (Unauthorized),尝试访问 r.json() 将会抛出 ValueError: No JSON object could be decoded 异常。
注意点,成功调用 r.json() 并不意味着响应的成功。有的服务器会在失败的响应中包含一个JSON对象(比如HTTP 500的错误细节)。这种 JSON 会被解码返回。要检查请求是否成功,请使用 r.raise_for_status() 或者检查r.status_code 是否和你的期望相同。
五、原始响应内容
在罕见的情况下,你可能想获取来自服务器的原始套接字响应,那么你可以访问 r.raw。如果你确定想这么干,那请你确保在初始请求中设置了 stream=True。具体你可以这么做:
>>> r = requests.get('https://api.github.com/events', stream=True) >>> r.raw <requests.packages.urllib3.response.HTTPResponse object at 0x101194810> >>> r.raw.read(10) '\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03'
但一般情况下,你应该以下面的模式将文本流保存到文件中:
with open(filename, 'wb') as fd: for chunk in r.iter_content(chunk_size): fd.write(chunk)
使用 Response.iter_content 将会处理大量你直接使用 Response.raw 不得不处理的。当流下载时,上面是优先推荐的获取内容方式。
六、定制请求头
如果你想为请求添加 HTTP 头部,只要简单地传递一个 dict 给 headers 参数就可以了。例如,在前一个示例中我们没有指定 content-type:
>>> url = 'https://api.github.com/some/endpoint' >>> headers = {'user-agent': 'my-app/0.0.1'} >>> r = requests.get(url, headers=headers)
注意:定制 header 的优先级低于某些特定的信息源,例如:
- 如果在
.netrc
中设置了用户认证信息,使用 headers= 设置的授权就不会生效。而如果设置了auth=
参数,``.netrc`` 的设置就无效了。 - 如果被重定向到别的主机,授权 header 就会被删除。
- 代理授权 header 会被 URL 中提供的代理身份覆盖掉。
- 在我们能判断内容长度的情况下,header 的 Content-Length 会被改写。
更进一步讲,Requests不会基于定制 header 的具体情况改变自己的行为。只不过在最后的请求中,所有的header 信息都会被传递进去。
注意: 所有的 header 值必须是 string
、bytestring 或者 unicode。尽管传递 unicode header 也是允许的,但不建议这样做。
七、更加复杂的POST请求
通常,你想要发送一些编码为表单形式的数据——非常像一个 HTML 表单。要实现这个,只需简单地传递一个字典给 data 参数。你的数据字典在发出请求时会自动编码为表单形式:
>>> payload = {'key1': 'value1', 'key2': 'value2'} >>> r = requests.post("http://httpbin.org/post", data=payload) >>> print(r.text) { ... "form": { "key2": "value2", "key1": "value1" }, ... }
你还可以为 data 参数传入一个元组列表。在表单中多个元素使用同一 key 的使用,这种方式 尤其有效:
>>> payload = (('key1', 'value1'), ('key1', 'value2')) >>> r = requests.post('http://httpbin.org/post', data=payload) >>> print(r.text) { ... "form": { "key1": [ "value1", "value2" ] }, ... }
很多时候你想要发送的数据并非编码为表单形式的。如果你传递一个 string
而不是一个 dict
,那么数据会被直接发布出去。例如,Github API v3 接受编码为 JSON 的 POST/PATCH 数据:
>>> import json >>> url = 'https://api.github.com/some/endpoint' >>> payload = {'some': 'data'} >>> r = requests.post(url, data=json.dumps(payload))
此处除了可以自行对 dict
进行编码,你还可以使用 json
参数直接传递,然后它就会被自动编码。这是 2.4.2 版的新加功能:
>> url = 'https://api.github.com/some/endpoint' >>> payload = {'some': 'data'} >>> r = requests.post(url, json=payload)