Python流式读取HTTP响应部分数据 不下载完整响应的实现方案
问题原因
你之前的代码没有主动关闭响应连接,requests 为了实现连接复用机制,会在你返回结果后,在后台静默把剩余的响应内容全部下载完成,再把连接放回连接池,所以才会出现逻辑上已经拿到了开头数据,实际还是跑完了完整响应下载的情况。
服务器不支持Range请求头的场景下,只要在拿到所需的开头数据后主动断开底层TCP连接,就可以终止后续内容的下载,不需要等响应传完。
调整后代码
import requests def get_data(change_id): url = "https://my-api.com?id={}".format(change_id) # 用with上下文管理响应,退出块时会自动强制关闭连接 with requests.get(url, stream=True, headers=headers, timeout=(3, 10)) as r: r.raise_for_status() # 先校验HTTP请求状态,处理4xx/5xx错误 prefix_buffer = b"" for chunk in r.iter_content(chunk_size=512): if not chunk: break prefix_buffer += chunk # 累计读取的内容足够匹配就直接返回 target_id = extract_change_id(prefix_buffer) if target_id is not None: return target_id # 加安全阈值:change_id固定在开头,最多读2KB还没匹配到就直接终止,避免异常情况浪费资源 if len(prefix_buffer) >= 2048: break # 匹配失败返回None return None
关键说明
- 必须通过
with语句或者显式调用r.close()来主动关闭响应,只要连接关闭,底层会直接中断TCP传输,不会继续下载剩余的大体积响应内容。 - 不要只读取第一个chunk就返回,用缓冲区累计前部分内容做匹配,避免第一个chunk因为网络分包、响应开头有冗余字符等原因没覆盖完整的change_id,导致正则匹配失败。
- 加上读取长度上限和超时配置,避免异常请求拖慢整个数据流的处理效率。
内容的提问来源于stack exchange,提问作者Titan Chase
相关产品推荐
相关产品推荐

