2014-12-06 79 views
2

下面兩行代碼掛起永遠: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

回答

2

如果運行

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