gpt4 book ai didi

python - 我如何*正确*在循环中运行 asyncio/aiohttp 请求?

转载 作者:行者123 更新时间:2023-12-05 01:00:26 27 4
gpt4 key购买 nike

我正在尝试同时请求一堆 URL,但是这些 URL 是从列表中构建的。目前我正在遍历列表并(我认为)将它们添加到队列中。它肯定比 requests.get 快 10 倍,但是我不确定我是否正确执行此操作,因此可以对其进行优化。我对其进行了分析,并注意到它在并发请求完成后仍有 90% 的时间处于锁定状态,即开始 -> 10+ 个并发请求 -> 锁定 5 秒左右 -> 完成

此外,此代码最后会产生 未关闭的客户端 session 消息。知道为什么吗?很确定这是正确使用上下文管理器。

我已经搜索并没有找到这个确切的问题

 import signal
import sys
import asyncio
import aiohttp
import json
import requests

lists = ['eth', 'btc', 'xmr', 'req', 'xlm', 'etc', 'omg', 'neo', 'btc', 'xmr', 'req', 'xlm', 'etc', 'omg', 'neo']

loop = asyncio.get_event_loop()
client = aiohttp.ClientSession(loop=loop)

async def fetch(client, url):
async with client.get(url) as resp:
assert resp.status == 200
return await resp.text()

async def main(loop=loop, url=None):
async with aiohttp.ClientSession(loop=loop) as client:
html = await fetch(client, url)
print(html)

def signal_handler(signal, frame):
loop.stop()
client.close()
sys.exit(0)

signal.signal(signal.SIGINT, signal_handler)
tasks = []
for item in lists:
url = "{url}/{endpoint}/{coin_name}".format(
url='https://coincap.io',
endpoint='page',
coin_name=item.upper()
)
print(url)
tasks.append(
asyncio.ensure_future(main(url=url))
)

loop.run_until_complete(asyncio.gather(*tasks))

最佳答案

看起来你有什么工作,但你认为你做的一切都不是很正确:

  • 您创建了一个从未使用过的客户端,并且没有正确关闭(导致 Unclosed client session)警告
  • 您正在为每个请求创建一个客户端,这比重用客户端效率低得多。
  • 您的大部分代码并未在正在运行的事件循环中运行。
  • 没有必要的信号处理程序,如果你有长时间运行的异步任务,你可能想要使用 add_signal_handler

这是我对您的代码的简化:

import asyncio
import aiohttp

lists = ['eth', 'btc', 'xmr', 'req', 'xlm', 'etc', 'omg', 'neo', 'btc', 'xmr', 'req', 'xlm', 'etc', 'omg', 'neo']


async def fetch(client, item):
url = 'https://coincap.io/{endpoint}/{coin_name}'.format(
endpoint='page',
coin_name=item.upper()
)
async with client.get(url) as resp:
assert resp.status == 200
html = await resp.text()
print(html)


async def main():
async with aiohttp.ClientSession() as client:
await asyncio.gather(*[
asyncio.ensure_future(fetch(client, item))
for item in lists
])


loop = asyncio.get_event_loop()
loop.run_until_complete(main())

如果你想随后处理 html,你可以在 fetch 协程中进行,也可以对 gather 的所有结果进行操作。

关于python - 我如何*正确*在循环中运行 asyncio/aiohttp 请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49869769/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com