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

Posted

技术标签:

【中文标题】Python 请求,如何限制接收大小、传输速率和/或总时间?【英文标题】:Python requests, how to limit received size, transfer rate, and/or total time? 【发布时间】:2014-03-12 08:45:23 【问题描述】:

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

请求的总时间超过了一定的限制(即使数据仍在到达) 接收的总大小超过了一些限制(我需要在接受更多数据之前取消) 传输速度下降到某个水平以下(尽管如果可以提供总时间限制,我可以不用这个)

注意我不是在请求中寻找timeout 参数,因为这只是不活动的超时。我找不到与总超时或限制总大小的方法有关的任何事情。一个示例显示了 HTTPAdapter 上的 maxsize 参数,但没有记录。

如何使用requests 实现这些要求?

【问题讨论】:

maxsize 是连接池的限制,我认为,而不是接收大小。 不是一个解决方案,但您还应该确保大小限制也考虑到标头的大小,而某些库(如 urllib)没有。 @ValentinLorentz,是的,我确实希望标题的大小限制比内容低得多。 关于总超时,您可能想看看我对类似问题的回答:***.com/a/22377499/1653521 【参考方案1】:

您可以尝试设置stream=True,然后在读取数据块时超出时间或大小限制时中止请求。

requests release 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 版本this change),您不能超时r.iter_content() 产量;在块中间停止响应的服务器仍然会占用连接。您必须将上述代码包装在一个额外的 timeout function 中,以尽早切断长时间运行的响应。

【讨论】:

一个小建议是在每个块到达时增加接收到的内容,就像您在your other answer 中所做的那样。 +1 @zx81:这就是 do something with chunk 评论的意义所在;您没有将所有内容收集到一个大字符串中,您也可以迭代处理它。 @MartijnPieters 是的,我看到了。这只是一个让代码对普通路人更直接有用的建议。不过不用担心,他们可以阅读 cmets。 :) 最良好的祝愿 应该注意的是,除非您 (a) 将数据写入磁盘或 (b) 处理内存中的流式数据(当它流式传输时),否则将块大小设置为您允许的最大块大小。读取小块大小会明显变慢,最终结果是无论如何都存储在内存中的数据。【参考方案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
               

【讨论】:

以上是关于Python 请求,如何限制接收大小、传输速率和/或总时间?的主要内容,如果未能解决你的问题,请参考以下文章

如何限制请求 python 库中 HTTP 请求的下载速率?

ASP.NET Core中如何限制响应发送速率(不是调用频率)

限制服务总线消息接收的 Azure Functions 速率

Kong入门指南 - 保护您的服务

Kong入门指南 - 保护您的服务

第8章 传输层_流量控制