1、requests模块的响应体内容工作流的运用
API引述
默认情况下,当你进行网络请求后,响应体会立即被下载。你可以通过 stream 参数覆盖这个行为,
推迟下载响应体直到访问 Response.content 属性:
tarball_url = 'https://github.com/kennethreitz/requests/tarball/master'
r = requests.get(tarball_url, stream=True)
此时仅有响应头被下载下来了,连接保持打开状态,因此允许我们根据条件获取内容:
if int(r.headers['content-length']) < TOO_LONG:
content = r.content
...
你可以进一步使用 Response.iter_content 和 Response.iter_lines 方法来控制工作流,或者以 Response.raw 从底层 urllib3 的 urllib3.HTTPResponse <urllib3.response.HTTPResponse 读取未解码的响应体。
如果你在请求中把 stream 设为 True,Requests 无法将连接释放回连接池,除非你 消耗了所有的数据,或者调用了 Response.close。 这样会带来连接效率低下的问题。如果你发现你在使用 stream=True 的同时还在部分读取请求的 body(或者完全没有读取 body),那么你就应该考虑使用 with 语句发送请求,这样可以保证请求一定会被关闭:
with requests.get('http://httpbin.org/get', stream=True) as r:
# 在此处理响应。
评注
这种方法与过去我们直接使用requests.get(url)
方法的区别在于:一般的请求上,我们都是直接将数据一次性拿回来,而使用工作流的方式,我们可以先取响应头。再对数据进行后续操作。
这让我们可以根据响应头的信息(响应内容长度、响应的形式等),决定是否需要获取数据(下载操作)
因此传统的操作,被我们分拆成如下的操作:
import requests
url = 'target_url'
response = requests.get(url,stream=True) # 此时我们已经下载了响应头和响应内容
#-------------------------------------
#-------------------------------------
import requests
url = 'target_url'
response = requests.get(url,stream=True) # 此时我们只下载了响应头
if response.headers['字段信息'] 满足 条件x:
print(response.content) # 此时才开始下载响应内容
response.close() #这一步不要遗漏
这种使用方法的运用还不仅于此,我们如果再结合API提供的函数requests.response.iter_content()
对工作流进行操作,就可以实现两种目的:
- 实时下载进度的更新
- 避免目标数据过大一次性读入内存处理的问题
代码实例:
# -*- coding: utf-8 -*-