Python 2.7 Python urllib2不考虑超时

Python 2.7 Python urllib2不考虑超时,python-2.7,urllib2,Python 2.7,Urllib2,以下两行代码永远挂起: import urllib2 urllib2.urlopen('https://www.5giay.vn/', timeout=5) 这是python2.7,我没有设置http_代理或任何其他环境变量。任何其他网站都可以。我也可以wget的网站没有任何问题。有什么问题吗?如果您运行 import urllib2 url = 'https://www.5giay.vn/' urllib2.urlopen(url, timeout=1.0) 等待几秒钟,然后使用C-C中

以下两行代码永远挂起:

import urllib2
urllib2.urlopen('https://www.5giay.vn/', timeout=5)
这是python2.7,我没有设置http_代理或任何其他环境变量。任何其他网站都可以。我也可以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.\u sslobj.read(len)上

您可以通过调用来控制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')


请注意,尽管
urllib2
没有:

import requests
r = requests.get('https://www.5giay.vn/')

如何对整个函数调用强制超时:

socket.setdefaulttimeout
仅影响在服务器未发出响应时Python在引发异常之前等待的时间

它和
urlopen(…,timeout=…)
都不对整个函数调用实施时间限制

要做到这一点,可以使用eventlet

如果不想安装
eventlets
,可以使用标准库中的
多处理
;尽管此解决方案的可扩展性不如
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秒的挂钟时间内成功或超时。

我在Linux(Amazon AMI)和Mac OS上都看到了这一点。而且,它似乎与DNS无关,因为即使这个挂起:urllib2.urlopen(“”,timeout=1)感谢您的调查。如果超时值为1,则会超时。但如果将超时设置为5.0,它将永远挂起。奇怪!谢谢,在本例中,Web服务器配置错误,每秒发送1个字符。因此,超时没有达到,请求仍将持续很久。
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')