【问题标题】:How to declare a timeout using urllib2 on Google App Engine?如何在 Google App Engine 上使用 urllib2 声明超时?
【发布时间】:2010-07-26 20:45:38
【问题描述】:

我知道 urllib2 在 Google App Engine 上可用作 Urlfetch 的包装器,而且如您所知,Universal Feedparser 使用 urllib2。

你知道在 urllib2 上设置超时的任何方法吗?
urllib2 上的timeout 参数是否已移植到 Google App Engine 版本上?

我对这样的方法不感兴趣:

rssurldata = urlfetch(rssurl, deadline=..)
feedparser.parse(rssurldata)

【问题讨论】:

  • 您是否有特定原因不想使用您刚刚概述的更简单的方法?
  • @Nick Hi :)! 嗯,仅仅是因为我正在使用的 feed 爬行库有点密封,应该保持 gae 不可知论。你能指出我在 gae 源代码上的 urllib2 包装器吗?我也不知道当前的 urllib2 超时设置为 5 秒还是最大为 10 秒(MAX Urlfetch Deadline)
  • 包装器将超时保留为默认值 5 秒。我不知道有什么方法可以通过包装器将超时值传递给 urlfetch API。不过,在事情的最后,你总是可以猴子补丁 urlfetch API 默认为 10 秒......

标签: google-app-engine urllib2 feedparser urlfetch


【解决方案1】:

据我所知,没有简单的方法可以做到这一点,因为包装器没有提供传递超时值的方法。一种骇人听闻的选择是对 urlfetch API 进行猴子补丁:

old_fetch = urlfetch.fetch
def new_fetch(url, payload=None, method=GET, headers={},
          allow_truncated=False, follow_redirects=True,
          deadline=10.0, *args, **kwargs):
  return old_fetch(url, payload, method, headers, allow_truncated,
                   follow_redirects, deadline, *args, **kwargs)
urlfetch.fetch = new_fetch

【讨论】:

  • 哪里是修补这个的正确位置?在调用爬虫库之前主要还是直接?
  • 在您使用 API 之前导入的任何模块中的顶级。
【解决方案2】:

我更喜欢这个。 GAE API 更新更加动态。

# -*- coding: utf-8 -*-
from google.appengine.api import urlfetch

import settings


def fetch(*args, **kwargs):
    """
    Base fetch func with default deadline settings
    """
    fetch_kwargs = {
        'deadline': settings.URL_FETCH_DEADLINE
    }
    fetch_kwargs.update(kwargs)
    return urlfetch.fetch(
        *args, **fetch_kwargs
    )

【讨论】:

    【解决方案3】:

    您可以设置默认截止日期,这是首选方式:

    from google.appengine.api import urlfetch
    import urllib, urllib2
    
    
    class MyClass():
    
        def __init__(self):
            urlfetch.set_default_fetch_deadline(10)
    

    我有一个开启器,我使用 urllib2 来启用 CookieJar,但你可以只做简单的请求

    response = self.opener.open(self.url_login, data_encoded)
    

    把deadline设置成0.1就可以很容易看到效果

    【讨论】:

      【解决方案4】:

      您是否尝试过设置套接字超时值?取自here

      从 Python 2.3 开始,您可以指定套接字在超时之前等待响应的时间。这在必须获取网页的应用程序中很有用。默认情况下,套接字模块没有超时并且可以挂起。目前,套接字超时未在 httplib 或 urllib2 级别公开。但是,您可以使用以下方法为所有套接字全局设置默认超时:

      import socket
      import urllib2
      
      # timeout in seconds
      timeout = 10
      socket.setdefaulttimeout(timeout)
      
      # this call to urllib2.urlopen now uses the default timeout
      # we have set in the socket module
      req = urllib2.Request('http://www.voidspace.org.uk')
      response = urllib2.urlopen(req)
      

      我不确定 GAE 是否会读取此值,但值得一试!

      编辑:

      urllib2具有传递超时参数的能力:

      可选的超时参数 以秒为单位指定超时 像这样的阻塞操作 连接尝试(如果未指定, 全局默认超时设置 将会被使用)。这实际上只是 适用于 HTTP、HTTPS、FTP 和 FTPS 连接.连接。

      【讨论】:

      • 是的,这是我的第一次尝试。套接字在 gae 上没有 setdefaulttimeout 方法 :)。感谢您的宝贵时间。
      • urllib2的超时参数呢?
      • 我在问“urllib2 上的超时参数是否已移植到 Google App Engine 版本上?”。
      猜你喜欢
      • 2011-05-05
      • 2011-05-16
      • 1970-01-01
      • 2011-06-05
      • 1970-01-01
      • 2011-01-10
      • 1970-01-01
      • 1970-01-01
      • 2018-09-04
      相关资源
      最近更新 更多