Python的urllib2的不尊重超时

问题描述:

下面两行代码挂起永远:Python的urllib2的不尊重超时

import urllib2 
urllib2.urlopen('https://www.5giay.vn/', timeout=5) 

这是python2.7,我也没有HTTP_PROXY或设置任何其他ENV变量。任何其他网站工作正常。我也可以没有任何问题的网站wget。可能是什么问题?

+0

我在Linux(Amazon AMI)和Mac OS上看到了这一点。此外,似乎并没有涉及DNS,因为即使这样挂起:urllib2.urlopen('https://210.245.123.158',timeout = 1) – user3822497 2014-12-06 04:27:01

如果运行

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秒的挂钟时间内成功或超时。

+0

感谢您的调查。超时时间为1时,超时。但是如果你让timeout = 5.0,它会永远挂起。奇怪! – user3822497 2014-12-06 06:48:58

+0

谢谢,在这种情况下,网络服务器配置错误,每秒发送1个字符。所以超时没有打,而且这个请求仍然会持续。 – user3822497 2014-12-06 21:31:56