requests
Python でモジュールを使用して API からデータを取得する方法を学び始めたところです。非常に単純な GET リクエストを使用してこの API を呼び出しますが、リクエストごとに異なる値を渡すだけで、500,000 回以上実行する必要があります。応答は JSON オブジェクトであり、必要なものを簡単に解析できます。
問題は、私がこれを行っている現在の方法であるfor-loop
usingrequests
が遅すぎることです。私が理解しているように、このアプローチはリクエストを送信し、レスポンスが完了するのを待ってから、イテラブル内の次のリクエストに移動します。
これを解決するために、grequest
非同期リクエストをサポートするモジュールに出会いました。このアプローチでは、おそらく 100 程度のバッチで、多くのクエリをすべて同時に開始できることを望んでいます。理想的には、これにより、大きな iterable をより迅速に移動できるようになります。
ドキュメントといくつかの例を読んで、以下の架空の例を作成しました。明らかに、これははるかに小さいデータセットであるため、すべての URL を小さなチャンクに分割して一度に送信するために使用する部分は含めていません。実際のデータセットに移る前に、このサンプル データセットを使用して自分の方法を証明したいと考えています。
現在、以下のコードで を使用するとtimeit
、各メソッドの結果のランタイムは次のようになります。
- for ループとリクエスト = 16.9 秒
- マッピングと非同期の grequests = 13.9 秒
私の質問は、 grequests メソッドがすべてのリクエストを同時に開始している場合、なぜそれが大幅に高速にならないのでしょうか? さらに、複数のリクエストを同時に送信する方法について何か提案はありますか?
# coding: utf-8
# In[1]:
import grequests
import requests
# In[2]:
# set up session
s = requests.session()
# In[3]:
# get a list of airports
airports = ['ATL', 'ORD', 'LAX', 'DFW', 'DEN', 'JFK', 'IAH', 'SFO', 'LAS', 'PHX',
'CLT', 'MIA', 'MCO', 'EWR', 'DTW', 'MSP', 'SEA', 'PHL', 'BOS', 'LGA',
'IAD', 'BWI', 'FLL', 'SLC', 'HNL', 'DCA', 'MDW', 'SAN', 'TPA', 'PDX',
'STL', 'MCI', 'MEM', 'MKE', 'OAK', 'CLE', 'RDU', 'BNA', 'SMF', 'HOU',
'SNA', 'AUS', 'MSY', 'SJC', 'PIT', 'SAT', 'CVG', 'DAL', 'IND']
# In[4]:
# build query string
def build_request(airport):
base_url = 'https://services.faa.gov/airport/status/'
request_string = base_url + airport + '/?format=application/json'
return request_string
# In[5]:
# create the request strings for all airports
urls = [build_request(a) for a in airports]
# In[7]:
def try_grequests(urls):
# create a set of unsent requests
rs = (grequests.get(u) for u in urls)
# send them all at the same time
data = grequests.map(rs)
return data
# In[10]:
def try_requests(urls):
# send requests one by one
data = [s.get(u).json() for u in urls]
return data
# In[11]:
# time how long it takes using grequests
get_ipython().magic(u'timeit try_grequests(urls)')
# In[12]:
# time how long it takes using requests
get_ipython().magic(u'timeit try_requests(urls)')