2012-02-16 29 views
0

我刚刚继承了一些Python代码,需要尽快修复一个错误。 我有很少的Python知识,所以请原谅我的无知。 我使用urllib2从网页提取数据。 尽管使用socket.setdefaulttimeout(30)我仍然遇到无限期挂起的URL。在Python 2.4中定时执行urllib2 urlopen操作

我想超时提取,并已走到这一步后,很多搜索网站:

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() 

的时间已经过去了,但我不知道如何得到它停止后的处理函数触发openurl操作。

任何指导将受到感谢。 C

UPDATE ------------------------- 根据我的经验,当在某些URL上使用urllib2.urlopen挂起并无限期地等待。 执行此操作的URL是指向浏览器指向时永不解析的URL,浏览器只是等待活动指示器移动,但从不完全连接。 我怀疑这些URL可能卡在某种无限循环重定向内。 urlopen(在更高版本的Python中)和socket.setdefaulttimeout()全局设置的timeout参数在我的系统上未检测到此问题。

我尝试了很多解决方案,但最终我更新为Python 2.7,并在下面使用了Werner答案的变体。谢谢Werner。

+0

通过 “使用套接字超时设置” 你的意思是'timeout'参数['urllib2.urlopen()'](http://docs.python.org/library/urllib2.html#urllib2。 urlopen),我想。奇怪,应该工作。 – 2012-02-16 13:46:28

+0

我使用Python 2.4,所以我不认为超时选项可用。相反,我使用导入套接字 socket.setdefaulttimeout(30)全局设置它。 – Columbo 2012-02-16 14:30:19

回答

2

可以使用信号实现这一目标。

下面是我的信号装饰器的一个示例,您可以使用它设置各个功能的超时时间。

Ps。不确定这是否符合2.4的语法。我使用的是2.6,但支持2.4的信号。

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

信号的超时是否受处理器时间影响?我试图使用像这个问题的作者的计时器线程没有成功。我想知道您的解决方案是否受到相同行为的影响 – 2012-04-19 13:52:08

2

它就在那里in the function

urllib2.urlopen(url[, data][, timeout]) 

e.g:

urllib2.urlopen("www.google.com", data, 5) 
+0

超时参数是可用的,因为2.6 – 2012-04-17 16:28:36

+0

@DiegoNavarro OP是使用2.4的事实直到我发布这个答案后才被指定。 – 2012-04-17 17:20:43