python urlopen函数的timeout_在Python 2.4中超时urllib2 urlopen操作

I've just inherited some Python code and need to fix a bug as soon as possible.

I have very little Python knowledge so please excuse my ignorance.

I am using urllib2 to extract data from web pages.

Despite using socket.setdefaulttimeout(30) I am still coming across URLs that hang seemingly indefinitely.

I want to time out the extraction and have got this far after much searching the web:

import socket

socket.setdefaulttimeout(30)

reqdata = urllib2.Request(urltocollect)

def handler(reqdata):

???? reqdata.close() ????

t = Timer(5.0, handler,[reqdata])

t.start()

urldata = urllib2.urlopen(reqdata)

t.cancel()

The handler function triggers after the time has passed but I don't know how to get it to stop the openurl operation.

Any guidance would be gratefully received.

C

UPDATE -------------------------

In my experience when used on certain URLs urllib2.urlopen hangs and waits indefinitely.

The URLs that do this are ones that when pointed to with a browser never resolve, the browser just waits with the activity indicator moving but never connecting fully.

I suspect that these URLs may be stuck inside some kind of infinite looping redirect.

The timeout argument to urlopen (in later versions of Python) and the socket.setdefaulttimeout() global setting do not detect this issue on my system.

I tried a number of solutions but in the end I updraded to Python 2.7 and used a variation of Werner’s answer below. Thanks Werner.

解决方案

You can achieve this using signals.

Here's an example of my signal decorator that you can use to set the timeout for individual functions.

Ps. not sure if this is syntactically correct for 2.4. I'm using 2.6 but the 2.4 supports signals.

import signal

import time

class TimeOutException(Exception):

pass

def timeout(seconds, *args, **kwargs):

def fn(f):

def wrapped_fn(*args, **kwargs):

signal.signal(signal.SIGALRM, handler)

signal.alarm(seconds)

f(*args, **kwargs)

return wrapped_fn

return fn

def handler(signum, frame):

raise TimeOutException("Timeout")

@timeout(5)

def my_function_that_takes_long(time_to_sleep):

time.sleep(time_to_sleep)

if __name__ == '__main__':

print 'Calling function that takes 2 seconds'

try:

my_function_that_takes_long(2)

except TimeOutException:

print 'Timed out'

print 'Calling function that takes 10 seconds'

try:

my_function_that_takes_long(10)

except TimeOutException:

print 'Timed out'

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值