Python中流式下载文件并按字节写入是否会发起两次HTTP请求?
请求逻辑及限流问题解答
核心问题答复:不会产生二次HTTP请求
你当前的代码写法全程仅发起1次HTTP请求,不存在多余请求:
- 调用
requests.get()时就已经完成了请求发送、响应头接收的全流程,此时就可以直接读取status_code等响应属性,和是否开启stream=True参数无关。 stream=True的作用仅为禁止提前将整个响应体加载到内存,后续调用iter_content迭代的是同一次请求返回的响应体数据流,不会触发新的HTTP请求。- 你配置的
Connection: keep-alive是用于复用TCP连接发起后续新请求,和本次请求是否重复发起没有关联。
速率偏低的排查方向
你遇到的限流问题和请求逻辑无关,可从以下点排查:
- 代码中的限流装饰器
@limits(calls=10, period=60)本身就将请求上限限制为每分钟10次,和你观测到的「每分钟不到10次」的表现完全吻合。 - 每次下载完成后你强制增加了
random.uniform(6, 7.2)秒的等待时间,按最小6秒计算,单线程下每分钟最多也只能发起10次请求,进一步挤压了请求上限。 @backoff.on_exception装饰器捕获了所有异常,包括触发429的请求,所有重试请求都会被目标站点计数,占用请求配额,拉高实际请求频次。- 部分IIS/ASP站点的限流规则会同时校验请求频率、单IP连接数、甚至请求间隔的离散程度,即使单线程低频率请求,如果请求间隔过于规律也可能被限流。
代码优化建议
- 修正两处
response.close的写法为response.close(),否则不会真的关闭响应连接,可能导致连接泄漏占用可用TCP连接数。 - 单独捕获429状态码异常,和其他异常区分开设置单独的重试等待时长,避免无意义的高频重试触发更严格的限流。
- 若可接受更低的速率,建议将
@limits的调用上限下调到每分钟5~8次,同时拉长两次请求之间的间隔,降低被限流的概率。
内容的提问来源于stack exchange,提问作者DataMinion
相关产品推荐
相关产品推荐

