Python的urllib2不遵守超时限制。
Python urllib2不遵守超时设定的原因是因为urllib2在处理HTTPS请求时,在读取服务器响应时出现了卡住的情况。解决方法是调用socket模块的setdefaulttimeout方法来设置超时时间,例如socket.setdefaulttimeout(1.0)。另外,还可以使用第三方库requests来发送HTTP请求,因为requests模块在处理HTTPS请求时能够成功遵守超时设定。如果想对整个函数调用设置超时时间,可以使用eventlets库或者multiprocessing库。使用eventlets库可以实现异步的超时设定,而使用multiprocessing库可以简单地设置超时时间,但不如异步解决方案那样高效。具体代码如下:
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')
以上代码使用multiprocessing库来实现超时设定,函数open中使用urllib2.urlopen来发送HTTP请求,然后使用timeout函数来设置超时时间为5秒。运行该代码,当超时时间内没有得到服务器响应时,程序会抛出TimeoutError异常,打印"timeout"。感谢您的调查,通过设置超时时间为1秒,确实会超时。但如果将超时时间设置为5秒,则会一直卡住。之所以会出现这种情况是因为web服务器的配置错误,每秒只发送1个字符,因此超时时间没有生效,请求会一直持续下去。