Python 遍历列表以获取 api 在 asyncio 中调用并保存结果
Python loop through list to get api call in asyncio and save results
我还没有完全理解 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 条我不想手动输入的请求。我怎样才能遍历我的列表?另外,如何将结果保存到变量中?当脚本结束时,它不会在任何地方保存 "results"。
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',
]
使用 gather
和辅助函数 (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)
对于你问题的另一部分,当你说:
When the script ends it does not save "results" anywhere.
如果您想在 main
协同程序之外访问 results
,您只需添加一条 return
语句即可。
在main
末尾添加:
return results
并改变
loop.run_until_complete(main())
# into:
results = loop.run_until_complete(main())
要将可变数量的参数传递给 gather
,请使用 *
函数参数语法:
results = await asyncio.gather(*[request(u) for u in urls])
请注意,f(*args)
是一项标准 Python 功能,用于调用 f
并在 运行 时计算位置参数。
results
将在所有请求完成后可用,并且它们将以与 URL 相同的顺序出现在列表中。然后你可以从 main
中 return 它们,这将导致它们被 run_until_complete
编辑 return。
此外,如果您只创建一次会话并为所有请求重用它,您将获得更好的性能,例如通过将其作为第二个参数传递给 request
函数。
我还没有完全理解 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 条我不想手动输入的请求。我怎样才能遍历我的列表?另外,如何将结果保存到变量中?当脚本结束时,它不会在任何地方保存 "results"。
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',
]
使用 gather
和辅助函数 (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)
对于你问题的另一部分,当你说:
When the script ends it does not save "results" anywhere.
如果您想在 main
协同程序之外访问 results
,您只需添加一条 return
语句即可。
在main
末尾添加:
return results
并改变
loop.run_until_complete(main())
# into:
results = loop.run_until_complete(main())
要将可变数量的参数传递给 gather
,请使用 *
函数参数语法:
results = await asyncio.gather(*[request(u) for u in urls])
请注意,f(*args)
是一项标准 Python 功能,用于调用 f
并在 运行 时计算位置参数。
results
将在所有请求完成后可用,并且它们将以与 URL 相同的顺序出现在列表中。然后你可以从 main
中 return 它们,这将导致它们被 run_until_complete
编辑 return。
此外,如果您只创建一次会话并为所有请求重用它,您将获得更好的性能,例如通过将其作为第二个参数传递给 request
函数。