我在python中构建了一个有趣的下载管理器,有时与服务器的连接仍然打开,但服务器不会向我发送数据,所以读取方法(HTTPResponse )永远阻挡我。例如,当我从位于我的国家以外的服务器下载时,会出现这种情况,从而限制了其他国家/地区的带宽。设置超时到http响应在python中读取方法
如何设置读取方法的超时时间(例如2分钟)?
谢谢,尼尔。
我在python中构建了一个有趣的下载管理器,有时与服务器的连接仍然打开,但服务器不会向我发送数据,所以读取方法(HTTPResponse )永远阻挡我。例如,当我从位于我的国家以外的服务器下载时,会出现这种情况,从而限制了其他国家/地区的带宽。设置超时到http响应在python中读取方法
如何设置读取方法的超时时间(例如2分钟)?
谢谢,尼尔。
您必须在HTTPConnection初始化期间进行设置。
注意:如果您使用的是旧版本的Python,那么您可以安装httplib2;很多人认为它是httplib的优越替代品,它支持timeout。
虽然我从来没有使用过它,但我只是在报告文档和博客在说什么。
+1,但请注意构造函数的timeout参数仅在python 2.6中可用+。 – 2010-04-03 23:40:18
对 - 我已经添加了一些关于httplib2的笔记 – 2010-04-03 23:53:36
我会尝试它,但我有点怀疑,因为HTTPResponse类的代码使用'makefile'方法,该方法无法通过文档获取超时:“该套接字必须处于阻止模式(不能有超时)“。 – user164524 2010-04-04 11:49:03
如果你被困在一些Python版本< 2.6
,一个(不完美,但可以使用)的做法是做
import socket
socket.setdefaulttimeout(10.0) # or whatever
在开始使用前httplib
。文档是here,并明确声明自Python 2.3以来可用的setdefaulttimeout
- 从您进行此调用时开始,到您再次调用相同函数为止的每个套接字都将使用10秒的超时时间。如果您想要保存先前的超时(包括无),可以在设置新的超时之前使用,以便稍后恢复(使用另一个setdefaulttimeout
)。
只要您需要使用一些使用Python socket
s的较旧的高级库,但不给您一个设置超时的好方法,这些函数和习语非常有用(当然,最好使用更新的更高级别库,例如在这种情况下带有2.6或第三方的httplib
版本,但这并非总是可行,并且使用默认超时设置播放可能是一种很好的解决方法)。
设置默认超时可能会提前终止下载,如果它很大,而不是只有在它停止接收超时值的数据时才中止。 HTTPlib2可能是要走的路。
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插槽(这应该是所有的人?)。你一定要多走几个层次更深:
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
说明
我在阅读此SO问题时偶然发现了这个问题setting a timeout on socket.recv
在一天结束时,任何http请求有一个插座。对于插座位于resp.raw._fp.fp._sock.socket
的httplib。 resp.raw._fp.fp._sock
是一个socket._fileobj
(我真的没有深入了解),我想它是settimeout
方法内部将它设置在socket
属性。
如果你想downvote答案,至少给一个人一个理由。 – Realistic 2015-12-12 19:17:50
相关:[使用urllib2或任何其他http库读取超时](http://stackoverflow.com/q/9548869/4279) – jfs 2016-02-08 10:31:01