【问题标题】:Timing out urllib2 urlopen operation in Python 2.4Python 2.4 中的 urllib2 urlopen 操作超时
【发布时间】:2012-03-07 21:51:06
【问题描述】:

我刚刚继承了一些 Python 代码,需要尽快修复一个错误。 我对Python的了解很少,所以请原谅我的无知。 我正在使用urllib2 从网页中提取数据。 尽管使用了socket.setdefaulttimeout(30),但我仍然遇到看似无限期挂起的 URL。

我想使提取超时,并且在网上搜索了很多之后得到了这个:

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

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

我尝试了许多解决方案,但最后我升级到 Python 2.7 并使用了下面 Werner 答案的变体。谢谢维尔纳。

【问题讨论】:

  • 我认为“使用套接字超时设置”是指timeout 参数到urllib2.urlopen()。奇怪,应该可以工作。
  • 我使用的是 Python 2.4,所以我认为超时选项不可用。相反,我使用 import socket.setdefaulttimeout(30) 全局设置它。

标签: python timer timeout urllib2 python-2.4


【解决方案1】:

您可以使用信号来实现这一点。

这是我的信号装饰器的一个示例,您可以使用它来设置各个函数的超时时间。

附言。不确定这在 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'

【讨论】:

  • 信号超时是否受处理器时间影响?我尝试像这个问题的作者一样使用 Timer 线程,但没有成功。我想知道您的解决方案是否受到相同行为的影响
【解决方案2】:

就在那里in the function

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

例如:

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

【讨论】:

  • 超时参数从 2.6 开始可用
  • @DiegoNavarro 直到我发布这个答案之后才指定 OP 使用 2.4 的事实。
猜你喜欢
  • 2011-03-31
  • 2011-01-06
  • 2012-11-24
  • 2012-08-18
  • 2019-03-11
  • 2013-04-07
  • 2011-12-23
  • 1970-01-01
  • 2012-04-11
相关资源
最近更新 更多