在python中将超时设置为http响应读取方法

时间:2010-04-03 23:32:03

标签: python timeout httpresponse

我正在python中构建一个下载管理器以获得乐趣,有时与服务器的连接仍然存在,但是服务器没有向我发送数据,因此读取方法(HTTPResponse)会永久阻止我。例如,当我从位于我国之外的服务器下载时,会将带宽限制在其他国家/地区。

如何设置读取方法的超时(例如2分钟)?

谢谢,Nir。

4 个答案:

答案 0 :(得分:3)

如果你坚持使用某些Python版本< 2.6,那么一种(不完美但可用)的方法就是

import socket
socket.setdefaulttimeout(10.0)  # or whatever

开始使用httplib之前。文档是here,并清楚地表明自从Python 2.3以来setdefaulttimeout可用 - 从您执行此调用时创建的每个套接字再次调用相同函数时将使用该超时10秒如果要保存先前的超时(包括无),可以在设置新的超时之前使用getdefaulttimeout,以便以后可以恢复(使用另一个setdefaulttimeout)。

这些函数和习惯用法非常有用,只要你需要使用一些使用Python socket的较旧的高级库,但是没有给你一个设置超时的好方法(当然最好使用更新)更高级别的库,例如2.6附带的httplib版本或本例中的第三方httplib2,但这并不总是可行,并且使用默认超时设置可以是一个很好的解决方法)

答案 1 :(得分:2)

您必须在HTTPConnection初始化期间进行设置。

注意:如果您使用的是旧版本的Python,则可以安装httplib2;许多人认为它是httplib的优秀替代品,它确实支持timeout 我从来没有用过它,而且我只是在报道文档和博客的内容。

答案 2 :(得分:1)

设置默认超时可能会在下载时提前中止,而不是仅在中止停止接收超时值的数据时中止。 HTTPlib2可能就是这样。

答案 3 :(得分:-1)

5年后,但希望这会帮助其他人......

我正在破坏我的大脑试图解决这个问题。我的问题是服务器返回损坏的内容,因此返回的数据少于它认为的数据。

我想出了一个似乎正常工作的讨厌的解决方案。在这里:

# NOTE I directly disabling blocking is not necessary but it represents
# an important piece to the problem so I am leaving it here.
# http_response.fp._sock.socket.setblocking(0)
http_response.fp._sock.settimeout(read_timeout)
http_response.read(chunk_size)

注意此解决方案也适用于 python请求 ANY 库,它实现了普通的python套接字(应该是所有这些套接字?) 。你只需要更深入一些:

resp.raw._fp.fp._sock.socket.setblocking()
resp.raw._fp.fp._sock.settimeout(read_timeout)
resp.raw.read(chunk_size)

在撰写本文时,我没有尝试过以下内容,但从理论上说它应该有效:

resp = requests.get(some_url, stream=True)
resp.raw._fp.fp._sock.socket.setblocking()
resp.raw._fp.fp._sock.settimeout(read_timeout)
for chunk in resp.iter_content(chunk_size):
      # do stuff

<强>解释

在阅读setting a timeout on socket.recv

的SO问题时,我偶然发现了这种方法

在一天结束时,任何http请求都有一个套接字。对于套接字位于resp.raw._fp.fp._sock.socket的httplib。 resp.raw._fp.fp._socksocket._fileobj(我老实说并没有深入研究),我想它的settimeout方法会在socket内部设置它。属性。