如果你跑了
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.timeout 之前的延迟
socket.setdefaulttimeout(1.0).
例如,
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 仅影响 Python 在引发异常之前等待的时间如果服务器没有发出响应。
它和urlopen(..., timeout=...) 都没有对整个函数调用实施时间限制。
为此,您可以使用 eventlet,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 秒后成功或超时。