使用asyncio进行多次调用并将结果添加到字典中

安东尼-丹德里亚

我在围绕Python 3的Asyncio库取得进展方面遇到了麻烦。我有一个邮政编码列表,我正在尝试对API进行异步调用,以获取每个邮政编码对应的城市和州。我可以使用for循环依次成功完成此操作,但在邮政编码列表较大的情况下,我想使其更快。

这是我的作品的一个例子

import urllib.request, json

zips = ['90210', '60647']

def get_cities(zipcodes):
    zip_cities = dict()
    for idx, zipcode in enumerate(zipcodes):
        url = 'http://maps.googleapis.com/maps/api/geocode/json?address='+zipcode+'&sensor=true'
        response = urllib.request.urlopen(url)
        string = response.read().decode('utf-8')
        data = json.loads(string)
        city = data['results'][0]['address_components'][1]['long_name']
        state = data['results'][0]['address_components'][3]['long_name']
        zip_cities.update({idx: [zipcode, city, state]})
    return zip_cities

results = get_cities(zips)
print(results)
# returns {0: ['90210', 'Beverly Hills', 'California'],
#          1: ['60647', 'Chicago', 'Illinois']}

这是我尝试使其异步的可怕的非功能性尝试

import asyncio
import urllib.request, json

zips = ['90210', '60647']
zip_cities = dict()

@asyncio.coroutine
def get_cities(zipcodes):
    url = 'http://maps.googleapis.com/maps/api/geocode/json?address='+zipcode+'&sensor=true'
    response = urllib.request.urlopen(url)
    string = response.read().decode('utf-8')
    data = json.loads(string)
    city = data['results'][0]['address_components'][1]['long_name']
    state = data['results'][0]['address_components'][3]['long_name']
    zip_cities.update({idx: [zipcode, city, state]})

loop = asyncio.get_event_loop()
loop.run_until_complete([get_cities(zip) for zip in zips])
loop.close()
print(zip_cities) # doesnt work

任何帮助深表感谢。我在网上遇到的所有教程似乎都令我有些头疼。

注意:我已经看到了一些使用示例aiohttp我希望尽可能使用本地Python 3库。

损伤

如果您用于urllib执行HTTP请求,那么您将无法获得任何并发性,因为它是一个同步库。包装的功能调用到urllibcoroutine不改变。您必须使用集成到中的异步HTTP客户端asyncio,例如aiohttp

import asyncio
import json
import aiohttp

zips = ['90210', '60647']
zip_cities = dict()

@asyncio.coroutine
def get_cities(zipcode,idx):
    url = 'https://maps.googleapis.com/maps/api/geocode/json?key=abcdfg&address='+zipcode+'&sensor=true'
    response = yield from aiohttp.request('get', url)
    string = (yield from response.read()).decode('utf-8')
    data = json.loads(string)
    print(data)
    city = data['results'][0]['address_components'][1]['long_name']
    state = data['results'][0]['address_components'][3]['long_name']
    zip_cities.update({idx: [zipcode, city, state]})

if __name__ == "__main__":        
    loop = asyncio.get_event_loop()
    tasks = [asyncio.async(get_cities(z, i)) for i, z in enumerate(zips)]
    loop.run_until_complete(asyncio.wait(tasks))
    loop.close()
    print(zip_cities)

我知道您更喜欢只使用stdlib,但是该asyncio库不包含HTTP客户端,因此您必须从根本上重新实现aiohttp其一部分才能重新创建其提供的功能。我想另一种选择是urllib在后台线程中进行调用,以使它们不会阻塞事件循环,但是在aiohttp可用时这样做很愚蠢的(并且首先打败了使用目的asyncio) :

import asyncio
import json
import urllib.request
from concurrent.futures import ThreadPoolExecutor

zips = ['90210', '60647']
zip_cities = dict()

@asyncio.coroutine
def get_cities(zipcode,idx):
    url = 'https://maps.googleapis.com/maps/api/geocode/json?key=abcdfg&address='+zipcode+'&sensor=true'
    response = yield from loop.run_in_executor(executor, urllib.request.urlopen, url)
    string = response.read().decode('utf-8')
    data = json.loads(string)
    print(data)
    city = data['results'][0]['address_components'][1]['long_name']
    state = data['results'][0]['address_components'][3]['long_name']
    zip_cities.update({idx: [zipcode, city, state]})

if __name__ == "__main__":
    executor = ThreadPoolExecutor(10)
    loop = asyncio.get_event_loop()
    tasks = [asyncio.async(get_cities(z, i)) for i, z in enumerate(zips)]
    loop.run_until_complete(asyncio.wait(tasks))
    loop.close()
    print(zip_cities)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

想要使用 for 循环多次运行查询并将每个结果添加到字典中。这段代码即使在循环时也只执行一次

使用Swift进行查询并将结果添加到结构中

使用xelement将结果添加到字典中

搜索Hashmap并将结果添加到列表中

根据冒号和换行符拆分字符串并将结果添加到字典中

根据值对python中的字典列表进行排序,并将排序后的对象添加到新列表中

使用dnorm创建循环并将结果添加到表中

如何使用字典将计算结果添加到数据框中?

添加到自为WaitAll字典结果

将池结果添加到字典

如何在XSLT中添加到模板调用的结果

如何使用 REGEX 读取 .txt 文件并计算单词的使用次数并将该信息添加到字典中

如何使用代码在C#中调用materialDesign组件并将其添加到wpf设计中?

转换字典中的2元组键,并将其作为字典值添加到新字典中

使用union将字典添加到`set()`中

使用 append 添加到字典内列表中的值

使用递归将项目添加到字典中

访问用户定义对象中的字典值并将它们添加到列表中

使用硒捕获数据并将其添加到字典以在数据框中使用

For 循环并将 <li> 添加到 <ul> 多次

计算变量中的重复值,并将结果添加到SPSS中的新值中

如何使用多个foursquare查询进行循环并将每个新查询添加到数据框中

Python-计算项目并将其添加到新字典中

用字典数据迭代Dictionary并将它迅速添加到数组中

python:如何溢出字典并将信息添加到数据框中的行?

将字典中的值与数据框行值匹配并将数据添加到该行

我想将pandas DataFrame中的两列相乘并将结果添加到新列中

如何在 postgreSQL 中重复查询,并将结果添加到表中

foreach中的异步方法并将结果添加到列表中