Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python在列表中循环以获取异步IO中的api调用并保存结果_Python_Request_Python Asyncio_Aiohttp - Fatal编程技术网

Python在列表中循环以获取异步IO中的api调用并保存结果

Python在列表中循环以获取异步IO中的api调用并保存结果,python,request,python-asyncio,aiohttp,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_pai

我还不完全理解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()
如果我使用索引(如下所示)逐个手动键入请求,我可以发出请求。但问题是,我的列表中有超过100个API请求,我不想手工输入。我如何反复浏览我的列表?另外,如何将结果保存到变量中?当脚本结束时,它不会将“结果”保存到任何地方

async def main():
    results = await asyncio.gather(
             request(urls[0]),
             request(urls[1]),
    )
    print(len(results))
    print(results)
下面是一些复制代码的示例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',
]

使用
collect
和助手函数(
request
)只会使一项非常简单的任务变得更加复杂和难以处理。您只需在所有单个请求中使用相同的
ClientSession
,同时将每个响应保存到结果列表中

async def main():
    results = []
    async with aiohttp.ClientSession() as session:
        for url in urls:
            async with session.get(url) as resp:
                results.append(await resp.text())
    print(len(results))
    print(results)

关于你问题的另一部分,当你说:

当脚本结束时,它不会将“结果”保存到任何地方

async def main():
    results = await asyncio.gather(
             request(urls[0]),
             request(urls[1]),
    )
    print(len(results))
    print(results)
如果您的意思是希望访问
main
corroutine之外的
results
,只需添加
return
语句即可

main
的末尾添加:

return results
改变

loop.run_until_complete(main())
# into:
results = loop.run_until_complete(main())

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

results = await asyncio.gather(*[request(u) for u in urls])
请注意,
f(*args)
是一个标准的Python特性,可以使用运行时计算的位置参数调用
f

所有请求完成后,
结果将可用,并且它们将以与URL相同的顺序出现在列表中。然后您可以从
main
返回它们,这将导致
run\u返回它们,直到完成


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

如上图所示,将
聚集
替换为
for
循环将导致请求一个接一个地检索,而不是并行检索。