Pythonの requests library のドキュメント内にあるサンプルを試しました。
async.map(rs)
を使用して、応答コードを取得しますが、要求された各ページのコンテンツを取得したいです。たとえば、これは機能しません。
out = async.map(rs)
print out[0].content
以下の答えは、リクエストv0.13.0 +に適用されるnotです。この質問が書かれた後、非同期機能は grequests に移動しました。ただし、以下のrequests
をgrequests
に置き換えるだけで機能します。
私はこのリクエストを、v0.13.0未満のリクエストの使用に関する元の質問を反映するためにそのまま残しました。
async.map
asynchronouslyで複数のタスクを実行するには:
async.map
を呼び出します例:
from requests import async
# If using requests > v0.13.0, use
# from grequests import async
urls = [
'http://python-requests.org',
'http://httpbin.org',
'http://python-guide.org',
'http://kennethreitz.com'
]
# A simple task to do to each response object
def do_something(response):
print response.url
# A list to hold our things to do via async
async_list = []
for u in urls:
# The "hooks = {..." part is where you define what you want to do
#
# Note the lack of parentheses following do_something, this is
# because the response will be used as the first argument automatically
action_item = async.get(u, hooks = {'response' : do_something})
# Add the task to our list of things to do via async
async_list.append(action_item)
# Do our list of things to do via async
async.map(async_list)
async
は、独立したモジュールgrequests
になりました。
こちらをご覧ください: https://github.com/kennethreitz/grequests
そしてそこに: Python経由で複数のHTTPリクエストを送信するための理想的な方法?
$ pip install grequests
スタックを構築します。
import grequests
urls = [
'http://www.heroku.com',
'http://tablib.org',
'http://httpbin.org',
'http://python-requests.org',
'http://kennethreitz.com'
]
rs = (grequests.get(u) for u in urls)
スタックを送る
grequests.map(rs)
結果は次のようになります
[<Response [200]>, <Response [200]>, <Response [200]>, <Response [200]>, <Response [200]>]
grequestsは、同時リクエスト、つまり複数のリクエストが同じサーバーに送信される場合の制限を設定していないようです。
requests-futuresとgrequestsの両方をテストしました。 Grequestsは高速ですが、モンキーパッチと依存関係に関する追加の問題をもたらします。 requests-futuresはgrequestsよりも数倍遅いです。独自の単純にラップされたリクエストをThreadPollExecutorに書き込むことにしました。これはgrequestsとほぼ同じ速さでしたが、外部依存関係はありませんでした。
import requests
import concurrent.futures
def get_urls():
return ["url1","url2"]
def load_url(url, timeout):
return requests.get(url, timeout = timeout)
with concurrent.futures.ThreadPoolExecutor(max_workers=20) as executor:
future_to_url = {executor.submit(load_url, url, 10): url for url in get_urls()}
for future in concurrent.futures.as_completed(future_to_url):
url = future_to_url[future]
try:
data = future.result()
except Exception as exc:
resp_err = resp_err + 1
else:
resp_ok = resp_ok + 1
多分 requests-futures は別の選択肢です。
from requests_futures.sessions import FuturesSession
session = FuturesSession()
# first request is started in background
future_one = session.get('http://httpbin.org/get')
# second requests is started immediately
future_two = session.get('http://httpbin.org/get?foo=bar')
# wait for the first request to complete, if it hasn't already
response_one = future_one.result()
print('response one status: {0}'.format(response_one.status_code))
print(response_one.content)
# wait for the second request to complete, if it hasn't already
response_two = future_two.result()
print('response two status: {0}'.format(response_two.status_code))
print(response_two.content)
オフィス文書 でも推奨されます。 geventに関与したくない場合は、良いイベントです。
私はこれがしばらく閉じられていることを知っていますが、要求ライブラリに基づいて構築された別の非同期ソリューションを促進することが役立つと思いました。
list_of_requests = ['http://moop.com', 'http://doop.com', ...]
from simple_requests import Requests
for response in Requests().swarm(list_of_requests):
print response.content
ドキュメントはこちらです: http://pythonhosted.org/simple-requests/
threads=list()
for requestURI in requests:
t = Thread(target=self.openURL, args=(requestURI,))
t.start()
threads.append(t)
for thread in threads:
thread.join()
...
def openURL(self, requestURI):
o = urllib2.urlopen(requestURI, timeout = 600)
o...
私はしばらくの間、githubのGist APIに対する非同期呼び出しにpythonリクエストを使用しています。
例については、次のコードを参照してください。
https://github.com/davidthewatson/flasgist/blob/master/views.py#L60-72
このスタイルのpythonは最も明確な例ではないかもしれませんが、コードが機能することを保証できます。これがあなたを混乱させるかどうか私に知らせてください、そして、私はそれを文書化します。
Asyncioを使用する場合、requests-async
はrequests
のasync/await機能を提供します- https://github.com/encode/requests-async
また、Pythonの非同期メソッドを使用していくつかのことを試しましたが、非同期プログラミングにツイストを使用した方がはるかに幸運でした。問題が少なく、十分に文書化されています。ここに、あなたが試しているものに似た何かのリンクがあります。
http://pythonquirks.blogspot.com/2011/04/twisted-asynchronous-http-request.html