Skip to main content
 首页 » 编程设计

python之谷歌应用引擎 : how to parallelize downloads using TaskQueue or Async Urlfetch

2025年05月04日9tuyile006

My Gae 应用程序从第三方站点检索 JSON 数据;给定一个表示要下载的项目的 ID,该网站上的项目数据组织在多个页面中,因此我的代码必须逐页下载数据 block ,直到检索到最后一个可用页面的数据。
我的简化代码如下所示:

class FetchData(webapp.RequestHandler): 
  def get(self): 
    ... 
    data_list = [] 
    page = 1 
    while True: 
      fetched_data= urlfetch.fetch('http://www.foo.com/getdata?id=xxx&result=JSON&page=%s' % page) 
      data_chunk = fetched_data["data"]  
      data_list = data_list + data_chunk 
      if len(data_list) == int(fetched_data["total_pages"]): 
         break 
      else: 
         page = page +1  
    ...   
    doRender('dataview.htm',{'data_list':data_list} ) 

data_list 结果是一个有序列表,第一项是第 1 页的数据,最后一项是最新页的数据;此 data_list 一旦被检索,就会在 View 中呈现。

这种方法在 99% 的情况下都有效,但有时,由于 Google App Engine 强加的 30 秒 限制,对于包含许多页面的项目,我会遇到可怕的 DeadlineExceededError。 我想知道是否使用 TaskQueue | Deferred | AsyncUrlfetch我可以改进此算法,以某种方式并行化 N 个 urlfetch 调用。

请您参考如下方法:

使用这个:http://code.google.com/appengine/docs/python/urlfetch/asynchronousrequests.html

像这样很简单:

def handle_result(rpc): 
    result = rpc.get_result() 
    # ... Do something with result... 
 
# Use a helper function to define the scope of the callback. 
def create_callback(rpc): 
    return lambda: handle_result(rpc) 
 
rpcs = [] 
for url in urls: 
    rpc = urlfetch.create_rpc() 
    rpc.callback = create_callback(rpc) 
    urlfetch.make_fetch_call(rpc, url) 
    rpcs.append(rpc) 
 
# ... 
 
# Finish all RPCs, and let callbacks process the results. 
for rpc in rpcs: 
    rpc.wait()