Python 2.6之前版本中urllib2.urlopen()的超时设置
urllib2的文档提到,timeout这个参数是在Python 2.6版本中新增的。可惜的是,我的代码现在还在使用Python 2.5和2.4的环境。
有没有其他方法可以模拟超时的功能呢?我只是想让代码和远程服务器交流一个固定的时间。
有没有什么内置的替代库?(我不想安装第三方库,比如pycurl)
6 个回答
2
我觉得你最好的选择是对你的urllib2进行修补(或者使用一个本地版本),可以参考2.6维护分支中的更改。
这个文件应该在 /usr/lib/python2.4/urllib2.py
这个路径下(在Linux系统和Python 2.4版本中)。
4
你可以很烦地去修改urllib2.HTTPHandler使用的httplib.HTTPConnection类。
def urlopen_with_timeout(url, data=None, timeout=None):
# Create these two helper classes fresh each time, since
# timeout needs to be in the closure.
class TimeoutHTTPConnection(httplib.HTTPConnection):
def connect(self):
"""Connect to the host and port specified in __init__."""
msg = "getaddrinfo returns an empty list"
for res in socket.getaddrinfo(self.host, self.port, 0,
socket.SOCK_STREAM):
af, socktype, proto, canonname, sa = res
try:
self.sock = socket.socket(af, socktype, proto)
if timeout is not None:
self.sock.settimeout(timeout)
if self.debuglevel > 0:
print "connect: (%s, %s)" % (self.host, self.port)
self.sock.connect(sa)
except socket.error, msg:
if self.debuglevel > 0:
print 'connect fail:', (self.host, self.port)
if self.sock:
self.sock.close()
self.sock = None
continue
break
if not self.sock:
raise socket.error, msg
class TimeoutHTTPHandler(urllib2.HTTPHandler):
http_request = urllib2.AbstractHTTPHandler.do_request_
def http_open(self, req):
return self.do_open(TimeoutHTTPConnection, req)
opener = urllib2.build_opener(TimeoutHTTPHandler)
opener.open(url, data)
58
你可以为所有的套接字操作(包括HTTP请求)设置一个全局的超时时间,方法是使用:
用法如下:
import urllib2
import socket
socket.setdefaulttimeout(30)
f = urllib2.urlopen('http://www.python.org/')
在这种情况下,你的urllib2请求将在30秒后超时,并抛出一个套接字异常。(这个功能是在Python 2.3中添加的)