如何加快API请求速度?

21

我使用谷歌地点API编写了一个用于获取电话号码的小程序,但速度非常慢。当我测试6个项目时,需要4.86秒至1.99秒不等,而我不确定时间变化的原因。我很少接触API,所以甚至不知道可以/无法加速哪些内容,哪些内容留给服务API的Web服务器处理,以及我可以自己改变什么。

import requests,json,time
searchTerms = input("input places separated by comma")

start_time = time.time() #timer
searchTerms = searchTerms.split(',')
for i in searchTerms:
    r1 = requests.get('https://maps.googleapis.com/maps/api/place/textsearch/json?query='+ i +'&key=MY_KEY')
    a = r1.json()
    pid = a['results'][0]['place_id']
    r2 = requests.get('https://maps.googleapis.com/maps/api/place/details/json?placeid='+pid+'&key=MY_KEY')
    b = r2.json()
    phone = b['result']['formatted_phone_number']
    name = b['result']['name']
    website = b['result']['website']
    print(phone+' '+name+' '+website)

print("--- %s seconds ---" % (time.time() - start_time))

我认为你必须考虑这里的各种时间因素。首先是程序从所提到的URL检索信息所需的时间(这将受到互联网速度和Web服务器发送响应所需的时间的影响)+ Python分析该信息所需的时间。我建议分别计算这两个时间,看看哪个时间更长,有多少变化。 - ρss
请记住,某个时刻您将会遇到 Google 地图 API 的速率限制 ;) - Tommaso Barbugli
5个回答

21
你可能希望并行发送请求。Python提供了multiprocessing模块,适用于此类任务。
示例代码:
from multiprocessing import Pool

def get_data(i):
    r1 = requests.get('https://maps.googleapis.com/maps/api/place/textsearch/json?query='+ i +'&key=MY_KEY')
    a = r1.json()
    pid = a['results'][0]['place_id']
    r2 = requests.get('https://maps.googleapis.com/maps/api/place/details/json?placeid='+pid+'&key=MY_KEY')
    b = r2.json()
    phone = b['result']['formatted_phone_number']
    name = b['result']['name']
    website = b['result']['website']
    return ' '.join((phone, name, website))

if __name__ == '__main__':
    terms = input("input places separated by comma").split(",")
    with Pool(5) as p:
        print(p.map(get_data, terms))

3
我的意思是问,if语句中包含的所有内容是什么。例如Pool(5)和p.map。 - click here
7
虽然我会提供一些解释,但可能对你来说已经晚了2.5年: 使用with Pool..创建Pool对象,该对象受上下文管理器控制,这意味着当程序退出with语句的作用域时,对象将被销毁并调用清理代码。 Pool(5)创建了一个线程池,其中包含5个能够独立运行的线程。 这意味着第二个HTTP请求不必等待第一个HTTP请求返回-因此,您可以一次性进行5次200ms等待,而不是按顺序执行5个需要200ms的操作。 - Dagrooms

14

3
这让我的速度提高了约33%!谢谢!(参考:136秒-> 91秒) - wjandrea
3
链接失效。尝试提交编辑,但编辑队列已满?这是新的链接 - Kevin M

6
大部分时间不是用来计算您的请求的,而是用在与服务器通信上。这是您无法控制的事情。
但是,您可以尝试使用并行化来加快速度。首先,为每个请求创建一个单独的线程。
from threading import Thread

def request_search_terms(*args):
    #your logic for a request goes here
    pass

#...

threads = []
for st in searchTerms:
    threads.append (Thread (target=request_search_terms, args=(st,)))
    threads[-1].start()

for t in threads:
    t.join();

随着请求数量的增加,请使用线程池,这将避免重复创建线程的开销。

1

这是客户端和服务器之间延迟的问题,除非使用多个服务器位置(接近客户端的服务器会收到请求),否则无法改变任何内容。

在性能方面,您可以构建一个多线程系统,可以同时处理多个请求。


1

您无需自行进行多线程处理。grequests 提供了一个快速的替代方案,可直接替换 requests。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接