Python的urllib2的不尊重超时
下面两行代码挂起永远:Python的urllib2的不尊重超时
import urllib2
urllib2.urlopen('https://www.5giay.vn/', timeout=5)
这是python2.7,我也没有HTTP_PROXY或设置任何其他ENV变量。任何其他网站工作正常。我也可以没有任何问题的网站wget。可能是什么问题?
如果运行
import urllib2
url = 'https://www.5giay.vn/'
urllib2.urlopen(url, timeout=1.0)
等待几秒钟,然后用C-C中断程序,你会看到
File "/usr/lib/python2.7/ssl.py", line 260, in read
return self._sslobj.read(len)
KeyboardInterrupt
这表明,该方案是挂在self._sslobj.read(len)
。
SSL timeouts raise socket.timeout
。
您可以通过调用 socket.setdefaulttimeout(1.0)
来控制socket.timeout之前的延迟。
例如,
import urllib2
import socket
socket.setdefaulttimeout(1.0)
url = 'https://www.5giay.vn/'
try:
urllib2.urlopen(url, timeout=1.0)
except IOError as err:
print('timeout')
% time script.py
timeout
real 0m3.629s
user 0m0.020s
sys 0m0.024s
注意the requests module这里成功虽然urllib2
没有:
import requests
r = requests.get('https://www.5giay.vn/')
如何执行关于整函数调用超时:
socket.setdefaulttimeout
只影响异常之前长的巨蟒等待如何提高如果服务器还没有发出响应。
它也没有urlopen(..., timeout=...)
执行整个函数调用的时间限制。
要做到这一点,您可以使用eventlets,as shown here。
如果你不想安装eventlets
,你可以使用标准库中的multiprocessing
;尽管这个解决方案不会像一个eventlets
提供的异步解决方案那么好。
import urllib2
import socket
import multiprocessing as mp
def timeout(t, cmd, *args, **kwds):
pool = mp.Pool(processes=1)
result = pool.apply_async(cmd, args=args, kwds=kwds)
try:
retval = result.get(timeout=t)
except mp.TimeoutError as err:
pool.terminate()
pool.join()
raise
else:
return retval
def open(url):
response = urllib2.urlopen(url)
print(response)
url = 'https://www.5giay.vn/'
try:
timeout(5, open, url)
except mp.TimeoutError as err:
print('timeout')
运行此操作将在大约5秒的挂钟时间内成功或超时。
感谢您的调查。超时时间为1时,超时。但是如果你让timeout = 5.0,它会永远挂起。奇怪! – user3822497 2014-12-06 06:48:58
谢谢,在这种情况下,网络服务器配置错误,每秒发送1个字符。所以超时没有打,而且这个请求仍然会持续。 – user3822497 2014-12-06 21:31:56
我在Linux(Amazon AMI)和Mac OS上看到了这一点。此外,似乎并没有涉及DNS,因为即使这样挂起:urllib2.urlopen('https://210.245.123.158',timeout = 1) – user3822497 2014-12-06 04:27:01