2011-02-10 9 views
11

私は、Webサービスに複数回リクエストを送信し、そのたびにパラメータが変更されるPythonのコールバックの種類の機能が必要です。私はこれらの要求を順次ではなく同時に発生させたいので、関数を非同期的に呼び出す必要があります。Pythonでの非同期HTTP呼び出し

asyncoreは私が使いたいかもしれないと思われますが、どのように動作しているか見てきた例はすべて、過度のように見えるので、別のパスがあるかどうかは疑問です。モジュール/プロセスに関する提案はありますか?理想的には、クラスを作成するのではなく手続き的な方法でこれらを使用したいと思いますが、私はそれを回避できないかもしれません。

+0

Way Overkill。私が必要とするのは、スクリプト内からの同時のhttp呼び出しです(コマンドラインなどからプロセスを呼び出す必要はありません)。私は単にコールバック機能を持っている必要がありますが、私はこれをPythonで見つけることができません。さらなる研究が私にurllib2を導いています。 – kasceled

+1

オーバーキル?スレッドは、コマンドラインからプロセスを呼び出すこととは関係ありません。 – Falmarri

+0

tippytop、もちろん、輸送用のurllib2 ..しかしあなたはまだそれを並行してスポーンする必要があります。スレッド化、マルチプロセッシング、concurrent.futures、またはasynch i/oベースのソリューションを実行できます。 –

答えて

8

Twisted frameworkはそのチケットです。しかし、あなたがそれを受けたくない場合は、pycurl、libcurl用のラッパーを使用することもできます。これは独自の非同期イベントループを持ち、コールバックをサポートします。

+0

私はこれを投稿したときにpycurlアプローチを取り戻しました(遅く受け入れて申し訳ありません)。 – kasceled

+1

@tippytop Cool。また、その上にラッパーを単純化することに興味があるかもしれません。 [pycopia.WWW.client](http://code.google.com/p/pycopia/source/browse/trunk/WWW/pycopia/WWW/client.py)モジュール。 – Keith

13

Python 3.2以降では、並列タスクの起動にconcurrent.futuresを使用できます。

チェックアウトこのThreadPoolExecutor例は:

http://docs.python.org/dev/library/concurrent.futures.html#threadpoolexecutor-example

これは、HTMLを取得するためのスレッドを生成し、それらが受信される応答に作用します。

import concurrent.futures 
import urllib.request 

URLS = ['http://www.foxnews.com/', 
     'http://www.cnn.com/', 
     'http://europe.wsj.com/', 
     'http://www.bbc.co.uk/', 
     'http://some-made-up-domain.com/'] 

# 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() 
     except Exception as exc: 
      print('%r generated an exception: %s' % (url, exc)) 
     else: 
      print('%r page is %d bytes' % (url, len(data))) 

上記の例ではスレッディングが使用されています。プロセスのプールではなく、スレッドを使用して同様のProcessPoolExecutorもあります:

http://docs.python.org/dev/library/concurrent.futures.html#processpoolexecutor-example

import concurrent.futures 
import urllib.request 

URLS = ['http://www.foxnews.com/', 
     'http://www.cnn.com/', 
     'http://europe.wsj.com/', 
     'http://www.bbc.co.uk/', 
     'http://some-made-up-domain.com/'] 

# 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() 
     except Exception as exc: 
      print('%r generated an exception: %s' % (url, exc)) 
     else: 
      print('%r page is %d bytes' % (url, len(data))) 
16

あなたはeventletについて知っていますか?これにより、同期コードのように見えるものを書くことができますが、ネットワーク上で非同期で動作させることができます。ここで

はスーパー最小限のクローラの例です:

urls = ["http://www.google.com/intl/en_ALL/images/logo.gif", 
    "https://wiki.secondlife.com/w/images/secondlife.jpg", 
    "http://us.i1.yimg.com/us.yimg.com/i/ww/beta/y3.gif"] 

import eventlet 
from eventlet.green import urllib2 

def fetch(url): 

    return urllib2.urlopen(url).read() 

pool = eventlet.GreenPool() 

for body in pool.imap(fetch, urls): 
    print "got body", len(body) 
0

(このスレッドは、サーバー側のPythonのについてですが、この質問は、しばらく前に頼まれたので、彼らが探しているところその他これにつまずくかもしれません。

クライアント側のソリューションについては、Async.jsライブラリ、特に "Control-Flow"セクションを参照してください。あなたが希望する結果を得ることができ、「滝」と「パラレル」を組み合わせることにより

https://github.com/caolan/async#control-flow

滝(パラレル(TaskA、TaskB、TaskC) - > PostParallelTask​​)

あなたがコントロールフロー下の例を調べると - "オート"、彼らはあなたに上記の例を与える: https://github.com/caolan/async#autotasks-callback 「書きます-file "は" get_data "と" make_folder "に依存し、" email_link "は書き込みファイルに依存します"

このすべてはクライアント側で発生します(Nodeを実行している場合を除きます)。JS - サーバー側)

サーバー側のPython用、pyCurlして以下の例を組み合わせることでhttps://github.com/pycurl/pycurl/blob/master/examples/basicfirst.py

@ PyCURLを見て、あなたはマルチスレッド、ノンブロッキングの機能を実現することができます。

これが役に立ちます。がんばろう。

Venkatt @http://MyThinkpond.com

関連する問題