Python requests,如何限制接收大小、传输速率和/或总时间?

22 投票
2 回答
36445 浏览
提问于 2025-04-17 21:54

我的服务器需要进行外部请求,但我想限制请求失败时可能造成的损害。我希望在以下情况下取消请求:

  • 请求的总时间超过某个限制(即使数据还在继续到达)
  • 接收到的数据总大小超过某个限制(我需要在接受更多数据之前取消)
  • 传输速度降到某个水平以下(不过如果能设置总时间限制,这个我可以不考虑)

需要注意的是,我并不是在寻找请求中的timeout参数,因为这个参数只是针对没有活动的超时。我找不到任何关于总超时或限制总大小的方法。有一个例子提到在HTTPAdapter上有一个maxsize参数,但这个没有文档说明。

我该如何使用requests来实现这些要求呢?

2 个回答

-2

对我来说,这个方法有效。

import requests

response = requests.get(your_url, stream=True, timeout=10)
response_content = [] #contains partial or full page_source 

for chunk in response.iter_content(1024):
    if len(chunk)>10000: # you can decide your chunk size limit(page_size)
       response_content.append(chunk)
       response.close()
       break
     else:
         response_content.append(chunk) # has full page source
         break
               

25

你可以试着设置 stream=True,然后在读取数据时,如果超出了你的时间或大小限制,就中止请求。

requests 版本 2.3.0 开始,超时设置也适用于流式请求,所以你只需要在初始连接和每次迭代时设置超时:

r = requests.get(..., stream=True, timeout=initial_timeout)
r.raise_for_status()

if int(r.headers.get('Content-Length')) > your_maximum:
    raise ValueError('response too large')

size = 0
start = time.time()

for chunk in r.iter_content(1024):
    if time.time() - start > receive_timeout:
        raise ValueError('timeout reached')

    size += len(chunk)
    if size > your_maximum:
        raise ValueError('response too large')

    # do something with chunk

根据需要调整超时时间。

对于 requests 版本低于 2.3.0(包含了 这个改动),你无法对 r.iter_content() 的返回结果设置超时;如果服务器在传输数据的过程中停止响应,连接仍然会被占用。你需要把上面的代码放在一个额外的 超时函数 中,以便提前结束长时间的响应。

撰写回答