1

現在のアプリケーションでは、TornadoAsyncHttpClientを使用して Web サイトにリクエストを送信しています。フローは複雑で、前のリクエストからのレスポンスを処理すると別のリクエストになります。

実際、私は記事をダウンロードしてから、それを分析し、その中で言及されている画像をダウンロードします

気になるのは、私のログには、.fetch()写真の URL が発行されたことを示すメッセージがはっきりと表示されているのに、 Wiresharkでスニッフィングされたように、実際の HTTP リクエストは行われていないことです。

max_client_count と Curl/Simple HTTP クライアントをいじってみましたが、動作は常に同じです。すべての記事がダウンロードされるまで、写真のリクエストは実際には発行されません。どうすればこれを変更できますか?

更新。いくつかの擬似コード

@VictorSergienko私はLinuxを使用しているため、デフォルトではEPollバージョンが使用されていると思います。システム全体は複雑すぎますが、要約すると次のようになります。

@gen.coroutine
def fetch_and_process(self, url, callback):
  body = yield self.async_client.fetch(url)
  res = yield callback(body)
  return res

@gen.coroutine
def process_articles(self,urls):
  wait_ids=[]
  for url in urls:
     #Enqueue but don't wait for one
     IOLoop.current().add_callback(self.fetch_and_process(url, self.process_article))
     wait_ids.append(yield gen.Callback(key=url))
  #wait for all tasks to finish
  yield wait_ids

@gen.coroutine
def process_article(self,body):
   photo_url=self.extract_photo_url_from_page(body)
   do_some_stuff()
   print('I gonna download that photo '+photo_url)
   yield self.download_photo(photo_url)

@gen.coroutine
def download_photo(self, photo_url):
  body = yield self.async_client.fetch(photo_url)
  with open(self.construct_filename(photo_url)) as f:
   f.write(body)

そして、それが印刷されたら、その写真をダウンロードします。実際のリクエストはありません! 代わりに、すべての記事がダウンロードされるまで、より多くの記事をダウンロードし、より多くの写真をエンキューし続けます。その後、すべての写真が一括で要求されます。

4

1 に答える 1

1

AsyncHTTPClient にはキューがあり、process_articles ですぐにいっぱいになります (「キューに入れますが、待つ必要はありません」)。最初の記事が処理されるまでに、その写真は他のすべての記事の後にキューの最後に配置されます。

process_articles で add_callback の代わりに使用yield self.fetch_and_processすると、記事とその写真を交互に表示することになりますが、一度に 1 つのものしかダウンロードできません。一度に複数のものをダウンロードしながら、記事と写真のバランスを維持するには、toro同期プリミティブ用のパッケージを使用することを検討してください。http://toro.readthedocs.org/en/stable/examples/web_spider_example.htmlの例は、ユース ケースに似ています。

于 2014-12-15T22:09:54.277 に答える