我刚刚开始学习如何使用Python中的requests
模块从API获取数据。我将使用一个非常简单的GET请求调用此API,但我需要做500,000次以上,只为每个请求传递不同的值。响应是一个JSON对象,我可以根据需要轻松解析它。
问题在于,我在for-loop
使用requests
的情况下执行此操作的方式过于缓慢。据我了解,这种方法是发送请求,等待响应完成,然后移动到iterable中的下一个请求。
为了解决这个问题,我遇到了支持异步请求的grequest
模块。通过这种方法,我希望能够同时启动许多查询,可能是100个左右。理想情况下,这将允许我更快地移动我的大型迭代。
通过阅读文档和几个例子,我在下面创建了一个假设的例子。显然这是一个小得多的数据集,所以我没有包含我将用来将所有URL分解为更小的块以便立即提交的部分。我希望在转移到我的真实数据集之前使用此样本数据集来证明我的方法。
目前,使用以下代码并使用timeit
,每种方法的运行时间如下:
我的问题是,如果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)')