1

我有一个 Google AppEngine(in Python) 应用程序,我需要在其中执行 4 到 5 次 url 获取,然后在将数据打印到响应之前组合数据。

我可以使用同步工作流毫无问题地做到这一点,但由于我正在获取的 url 不相关或相互依赖,因此异步执行此操作将是最理想的(也是最快的)。

我已经阅读并重新阅读了此处的文档,但我只是不知道如何阅读每个 url 的内容。我还在网上搜索了一个小例子(这确实是我需要的)。我已经看到了这个SO question,但同样,这里他们没有提到任何关于阅读这些单独的异步 url 获取的内容。

有没有人有任何简单的例子来说明如何使用 AppEngine 执行 4 或 5 个异步 url 获取?然后在将结果打印到响应之前组合结果?

这是我到目前为止所拥有的:

rpcs = []
for album in result_object['data']:
  total_facebook_photo_count = total_facebook_photo_count + album['count']
  facebook_albumid_array.append(album['id'])

  #Get the photos in the photo album
  facebook_photos_url = 'https://graph.facebook.com/%s/photos?access_token=%s&limit=1000' % (album['id'], access_token)

  rpc = urlfetch.create_rpc()
  urlfetch.make_fetch_call(rpc, facebook_photos_url)
  rpcs.append(rpc)

for rpc in rpcs:
  result = rpc.get_result()
  self.response.out.write(result.content)

但是,它仍然看起来像以下行: result = rpc.get_result() 强制它等待第一个请求完成,然后是第二个,然后是第三个,依此类推。有没有办法在收到结果时简单地将结果放入变量中?

谢谢!

4

2 回答 2

2

示例中,text = result.content是您获取内容(正文)的地方。

要并行获取 url,您可以设置它们,添加到列表并随后检查结果。扩展已经提到的示例,它可能看起来像:

from google.appengine.api import urlfetch

futures = []
for url in urls:
    rpc = urlfetch.create_rpc()
    urlfetch.make_fetch_call(rpc, url)
    futures.append(rpc)

contents = []
for rpc in futures:
    try:
        result = rpc.get_result()
        if result.status_code == 200:
            contents.append(result.content)
            # ...
    except urlfetch.DownloadError:
        # Request timed out or failed.
        # ...

concatenated_result = '\n'.join(contents)

在这个例子中,我们组装了所有返回状态码 200 的请求的主体,并在它们之间用换行符连接起来。

或者使用ndb,我个人对 GAE 上任何异步的偏好,例如:

@ndb.tasklet
def get_urls(urls):
  ctx = ndb.get_context()
  result = yield map(ctx.urlfetch, urls)
  contents = [r.content for r in result if r.status_code==200]
  raise ndb.Return('\n'.join(contents))
于 2013-02-18T20:25:53.403 回答
1

我使用这段代码(在我了解 ndb tasklets 之前实现):

    while rpcs:
      rpc = UserRPC.wait_any(rpcs)
      result = rpc.get_result()
      # process result here
      rpcs.remove(rpc)
于 2013-02-21T17:11:09.263 回答