2013-11-20 5 views
6

アイデアは簡単です:複数のHTTPリクエストを並行して送信する必要があります。Python 3で複数のHTTPリクエストを送信する最良の方法は何ですか?

私は基本的に複数のスレッドを生成するためにrequests-futuresライブラリを使用することに決めました。

今、私は約200のリクエストを持っていますが、まだかなり遅いです(私のラップトップで約12秒かかる)。また、コールバックを使用してレスポンスjsonを解析しています(ライブラリのドキュメントで提案されています)。また、要求の数に応じて最適なスレッド数を把握するための経験則がありますか?

基本的に、私はそれらの要求をさらにスピードアップできるかどうか疑問に思っていました。

+0

どのバージョンのpythonですか?あなたのstdlibオプションは2.7から3.3にかなり大幅に変更されます。 – roippi

+0

私はurllib + Threadingモジュールを提案しようとしていましたが、リンクしたパッケージは基本的に同じことをしています。私のラップトップ(MacBook Pro、3.2 GHzプロセッサ、16 GB RAM)で問題なく、25個ほどのスレッドを実行しました。 – BenDundee

+0

@roippi私はpythonを使用しています。3.3 –

答えて

6

あなたはPython 3.3を使用しているので、@ njzk2:concurrent.futuresによってリンクされたスレッドで見つからないstdlibソリューションをお勧めします。

これは、threadingまたはmultiprocessingプリミティブを直接処理するよりも高いレベルのインターステージです。プーリングと非同期レポートを処理するためのインターフェイスはExecutorです。

ドキュメントは基本的には自分の状況に直接適用した例を持っているので、私はちょうどそれをここにドロップします:あなたがそう望む場合は、requests呼び出しでurllib.request呼び出しを置き換えることができます

import concurrent.futures 
import urllib.request 

URLS = #[some list of urls] 

# Retrieve a single page and report the url and contents 
def load_url(url, timeout): 
    conn = urllib.request.urlopen(url, timeout=timeout) 
    return conn.readall() 

# We can use a with statement to ensure threads are cleaned up promptly 
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor: 
    # Start the load operations and mark each future with its URL 
    future_to_url = {executor.submit(load_url, url, 60): url for url in URLS} 
    for future in concurrent.futures.as_completed(future_to_url): 
     url = future_to_url[future] 
     try: 
      data = future.result() 
      # do json processing here 
     except Exception as exc: 
      print('%r generated an exception: %s' % (url, exc)) 
     else: 
      print('%r page is %d bytes' % (url, len(data))) 

。私は明らかな理由から、requestsが好きな傾向があります。

APIはちょっと変わっています。つまり、関数の非同期実行を表すFutureオブジェクトを作りなさい。次に、Futureインスタンスに対してイテレータを与えるためにconcurrent.futures.as_completedを使用します。それが完了すると、それが返されます。あなたの質問については

また、リクエスト数の関数として スレッドの最適な数を把握するための経験則があり、任意のはありますか?

ルールは、それはあなたのインターネット接続の速度を含む、あまりにも多くのものに依存します。私は実際にあなたが持っている要求の数に依存しない、より多くのハードウェアを実行していると言うでしょう。

幸いなことに、max_workers kwargを調整して自分でテストするのはかなり簡単です。 5または10のスレッドから開始し、5ずつ増やしていく。ある時点では、パフォーマンスの低下が目立ち、スレッドの追加によるオーバーヘッドが増加した並列化の限界利益(ワード)を追い越し、 。

+0

AWSマシンで以前に実行したオープン・スレッドに関する制限がありますが、私のラップトップではありません。この問題はここで概説されています:http://www.alak.cc/2011/11/python-threaderror-cant-start-new.html – BenDundee

+0

@roippiあなたは私の元の投稿で敬意を表しているリクエスト - 先物モジュールを見ましたか? ?ほとんど同じコードを実装しています。 –

+0

@NikolayDerkachいいえ私はしませんでしたが、それを見て..ハァッ!これは基本的に上記の1つのAPI呼び出しにラップされています。その1つの問題は、遅く/誤動作している場合、それを微調整するための手段がないということです。たとえば、物事がうまくいかなくなったときに、上記のコードを簡単に計ることができます。とにかく、幸運:) – roippi

関連する問題