我有一个Google AppEngine
(在Python
)应用程序中,我需要执行4到5次网址提取,然后在将数据打印到响应之前合并数据。
我可以使用同步工作流程毫无问题地执行此操作,但由于我提取的网址彼此不相关或相互依赖,因此异步执行此操作将是最理想的(也是最快的)。
我已阅读并重新阅读文档here,但我无法弄清楚如何阅读每个网址的内容。我也在网上搜索了一个小例子(这正是我真正需要的)。我已经看到了this SO问题,但是在这里他们没有提到任何关于阅读这些单独的异步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()强制它等待第一个请求完成,然后是第二个,然后是第三个,依此类推。有没有办法简单地将结果放入收到的变量中?
谢谢!
答案 0 :(得分:2)
在example中,text = result.content
是您获取内容(正文)的地方。
要在并行中进行网址提取,您可以设置它们,添加到列表中并在之后检查结果。扩展已经提到的示例,它可能看起来像:
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))
答案 1 :(得分:1)
我使用此代码(在了解ndb tasklets 之前已实现):
while rpcs:
rpc = UserRPC.wait_any(rpcs)
result = rpc.get_result()
# process result here
rpcs.remove(rpc)