【问题标题】:Fetching a lot of urls in python with google app engine使用谷歌应用引擎在python中获取大量网址
【发布时间】:2014-10-28 13:56:41
【问题描述】:

在我的 RequestHandler 子类中,我正在尝试获取 url 范围:

class GetStats(webapp2.RequestHandler):
    def post(self): 

    lastpage = 50   
    for page in range(1, lastpage):
        tmpurl = url + str(page)
        response = urllib2.urlopen(tmpurl, timeout=5)
        html = response.read()
        # some parsing html
        heap.append(result_of_parsing)  

    self.response.write(heap)

但它适用于大约 30 个网址(页面加载时间很长,但它是有效的)。 如果超过 30 我收到错误:

错误:服务器错误

服务器遇到错误,无法完成您的请求。

请在 30 秒后重试。

有没有办法获取大量的网址?可能是更优化的还是smth? 多达数百页?

更新:

我正在使用 BeautifulSoup 来解析每一页。我在 gae 日志中找到了这个回溯:

Traceback (most recent call last):
  File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/runtime/wsgi.py", line 267, in Handle
result = handler(dict(self._environ), self._StartResponse)
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 1529, in __call__
rv = self.router.dispatch(request, response)
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 1278, in default_dispatcher
return route.handler_adapter(request, response)
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 1102, in __call__
return handler.dispatch()
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 570, in dispatch
return method(*args, **kwargs)
  File "/base/data/home/apps/s~gae/1.379703839015039430/main.py", line 68, in post
heap = get_times(tmp_url, 160)
  File "/base/data/home/apps/s~gae/1.379703839015039430/main.py", line 106, in get_times
soup = BeautifulSoup(html)
  File "libs/bs4/__init__.py", line 168, in __init__
self._feed()
  File "libs/bs4/__init__.py", line 181, in _feed
self.builder.feed(self.markup)
  File "libs/bs4/builder/_htmlparser.py", line 56, in feed
super(HTMLParserTreeBuilder, self).feed(markup)
  File "/base/data/home/runtimes/python27/python27_dist/lib/python2.7/HTMLParser.py", line 114, in feed
self.goahead(0)
  File "/base/data/home/runtimes/python27/python27_dist/lib/python2.7/HTMLParser.py", line 155, in goahead
startswith = rawdata.startswith
 DeadlineExceededError

【问题讨论】:

  • 所有请求是否都发送到同一个服务器/域名?
  • @jDourlens 是的。
  • 您的所有请求是否在 60 秒内完成?您只有 60 秒的时间来返回请求。试着把它放到一个任务或类似的任务中。
  • 服务器可能会在短时间内阻止来自同一客户端的多次访问他的页面。也许是为了 ddos​​ 或报废保护.. 与不同的客户端重新连接或在通话之间等待(睡眠),您无能为力
  • 查看日志并提供有关错误的更多信息。这可能只是来自应用引擎的截止日期错误

标签: python google-app-engine python-2.7 webapp2


【解决方案1】:

它失败了,因为您只有 60 秒的时间向用户返回响应,而我猜它需要更长的时间。

你会想要使用这个:https://cloud.google.com/appengine/articles/deferred

创建一个有 10 分钟超时的任务。然后您可以立即返回给用户,他们可以稍后通过另一个处理程序(您创建的)“获取”结果。如果收集所有 URL 需要超过 10 分钟,您将不得不将它们拆分为更多任务。

看到这个:https://cloud.google.com/appengine/articles/deadlineexceedederrors

了解为什么不能超过 60 秒。

【讨论】:

  • 我怎样才能抓住工作完成的那一刻?用于向用户显示结果。
  • 在初始请求中将它们发送到一个 URL,您稍后将在该 URL 中提供结果(例如 /result/job1001 )。然后编写一些 Javascript 以每 10 秒从客户端刷新该页面。然后,当结果可用时,它们将在 10 秒内显示给用户。当然还有其他选择。
【解决方案2】:

编辑: 可能来自 Appengine 配额和限制。 抱歉之前的回答:

因为这看起来像是对服务器的保护,用于避免 ddos​​ 或从一个客户端报废。你有几个选择:

  • 在一定数量的查询之间等待,然后再继续。

  • 向具有不同 IP 地址的多个客户端发出请求并将信息发送回您的主脚本(为此租用不同的服务器可能成本很高..)。

  • 您还可以观看网站是否作为 api 来访问您需要的数据。

您还应该注意,如果站点所有者认为您的请求不好,他可能会阻止/将您的 IP 列入黑名单。

【讨论】:

    猜你喜欢
    • 2023-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-11
    相关资源
    最近更新 更多