2010-04-03 103 views
1

我在python中构建了一个有趣的下载管理器,有时与服务器的连接仍然打开,但服务器不会向我发送数据,所以读取方法(HTTPResponse )永远阻挡我。例如,当我从位于我的国家以外的服务器下载时,会出现这种情况,从而限制了其他国家/地区的带宽。设置超时到http响应在python中读取方法

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

谢谢,尼尔。

+0

相关:[使用urllib2或任何其他http库读取超时](http://stackoverflow.com/q/9548869/4279) – jfs 2016-02-08 10:31:01

回答

2

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

注意:如果您使用的是旧版本的Python,那么您可以安装httplib2;很多人认为它是httplib的优越替代品,它支持timeout
虽然我从来没有使用过它,但我只是在报告文档和博客在说什么。

+0

+1,但请注意构造函数的timeout参数仅在python 2.6中可用+。 – 2010-04-03 23:40:18

+0

对 - 我已经添加了一些关于httplib2的笔记 – 2010-04-03 23:53:36

+0

我会尝试它,但我有点怀疑,因为HTTPResponse类的代码使用'makefile'方法,该方法无法通过文档获取超时:“该套接字必须处于阻止模式(不能有超时)“。 – user164524 2010-04-04 11:49:03

3

如果你被困在一些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版本,但这并非总是可行,并且使用默认超时设置播放可能是一种很好的解决方法)。

1

设置默认超时可能会提前终止下载,如果它很大,而不是只有在它停止接收超时值的数据时才中止。 HTTPlib2可能是要走的路。

-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插槽(这应该是所有的人?)。你一定要多走几个层次更深:

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属性。

+1

如果你想downvote答案,至少给一个人一个理由。 – Realistic 2015-12-12 19:17:50