Python循环遍历列表以在asyncio中获取api调用并保存结果

Fed*_*ese 6 python request python-asyncio aiohttp

我还不完全理解 asyncio 和 aiohttp 是如何工作的。

我正在尝试从 URL 列表中发出一堆异步 api 请求,并将它们保存为变量,以便稍后处理它们。

到目前为止,我正在生成没有问题的列表并设置请求框架。

urls = []
for i in range(0,20):
    urls.append('https://api.binance.com/api/v1/klines?symbol={}&interval= 
    {}&limit={}'.format(pairs_list_pairs[i],time_period,
            pull_limit))

import asyncio
import aiohttp


async def request(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as resp:
            return await resp.text()


async def main():
    results = await asyncio.gather(
             request(urls[0]),
             request(urls[1]),
    )
    print(len(results))
    print(results)



loop = asyncio.get_event_loop()
try:
    loop.run_until_complete(main())
    loop.run_until_complete(loop.shutdown_asyncgens())
finally:
    loop.close()
Run Code Online (Sandbox Code Playgroud)

如果我使用索引手动一一输入我的请求(如下所示),我就可以发出请求。但问题是我的列表中有超过 100 个 api 请求,我不想手动输入这些请求。如何迭代我的列表?另外,如何将结果保存到变量中?当脚本结束时,它不会在任何地方保存“结果”。

async def main():
    results = await asyncio.gather(
             request(urls[0]),
             request(urls[1]),
    )
    print(len(results))
    print(results)
Run Code Online (Sandbox Code Playgroud)

下面是一些复制代码的示例 URL:

[
 'https://api.binance.com/api/v1/klines?symbol=ETHBTC&interval=15m&limit=1',
 'https://api.binance.com/api/v1/klines?symbol=LTCBTC&interval=15m&limit=1',
 'https://api.binance.com/api/v1/klines?symbol=BNBBTC&interval=15m&limit=1',
 'https://api.binance.com/api/v1/klines?symbol=NEOBTC&interval=15m&limit=1',
]
Run Code Online (Sandbox Code Playgroud)

use*_*342 4

要将可变数量的参数传递给gather,请使用*函数参数语法:

results = await asyncio.gather(*[request(u) for u in urls])
Run Code Online (Sandbox Code Playgroud)

请注意,这f(*args)是一个标准的 Python 功能,可f通过运行时计算的位置参数进行调用。

results所有请求完成后将可用,并且它们将以与 URL 相同的顺序出现在列表中。然后您可以从 退回它们main,这将导致它们被 退回run_until_complete

此外,如果您只创建一次会话,并将其重用于所有请求,例如将其作为第二个参数传递给函数,您将获得更好的性能request