使用Python urllib2.urlopen检测挂起

Dav*_*idM 13 python sockets networking

我正在使用Python的urllib2发送HTTP帖子:

import socket, urllib, urllib2

socket.setdefaulttimeout(15)    

postdata = urllib.urlencode({'value1' : 'a string', 'value2' : 'another string'})
headers = {
    'User-Agent': 'Agent',
    'Content-Type': 'application/x-www-form-urlencoded',
    'Accept': 'text/html, */*',
}

try: 
    request = urllib2.Request('http://www.example.com', postData, headers)
    response = urllib2.urlopen(request)
except urllib2.HTTPError, e:
    # Handle here
except urllib2.URLError, e:
    # Handle here
except httplib.HTTPException, e:
    # Handle here
Run Code Online (Sandbox Code Playgroud)

偶尔网络问题会导致对urlopen的调用永远不会返回.我们看到except块正确处理了其他错误(包括超时)并调用了socket.setdefaulttimeout(),但仍然存在urlopen永远不会返回的实例.

我知道它永远不会返回,因为我们的实际代码中有一些日志行会在之前和之后被调用,并且当出现此问题时,只会进行之前的调用并且脚本将永久挂起.

检测/处理此问题的最佳方法是什么?

Man*_*uel 10

您可以使用信号,首先为信号设置处理程序

import signal
...
def handler(signum, frame):
    print 'Signal handler called with signal', signum
...
signal.signal(signal.SIGALRM, handler)
Run Code Online (Sandbox Code Playgroud)

并在urlopen电话之前发出警报

signal.alarm(5)
response = urllib2.urlopen(request)
signal.alarm(0) # Disable the signal
Run Code Online (Sandbox Code Playgroud)

在5秒钟(或您想要的时间)之后,如果警报未被禁用(如果urlopen永远不会返回),操作系统将调用处理程序.有关信号模块的更多信息:http: //docs.python.org/library/signal.html

  • 这不适用于Windows(不支持`signal.alarm()`) (2认同)