Tam*_*lei 7 python python-asyncio aiohttp
作为一项学习练习,我试图修改aiohttp的快速入门示例,以使用单个ClientSession提取多个URL(文档建议通常应为每个应用程序创建一个ClientSession)。
import aiohttp
import asyncio
async def fetch(session, url):
async with session.get(url) as response:
return await response.text()
async def main(url, session):
print(f"Starting '{url}'")
html = await fetch(session, url)
print(f"'{url}' done")
urls = (
"https://python.org",
"https://twitter.com",
"https://tumblr.com",
"https://example.com",
"https://github.com",
)
loop = asyncio.get_event_loop()
session = aiohttp.ClientSession()
loop.run_until_complete(asyncio.gather(
*(loop.create_task(main(url, session)) for url in urls)
))
# session.close() <- this doesn't make a difference
Run Code Online (Sandbox Code Playgroud)
但是,在协程之外创建ClientSession显然不是可行的方法:
?python 1_async.py 1_async.py:30:用户警告:在协程之外创建客户端会话是一个非常危险的想法 会话= aiohttp.ClientSession() 在协程之外创建客户端会话 client_session: 开始'https://python.org' 开始“ https://twitter.com” 开始'https://tumblr.com' 开始“ https://example.com” 开始'https://github.com' 'https://twitter.com'完成 “ https://example.com”完成 'https://github.com'完成 'https://python.org'完成 'https://tumblr.com'完成 1_async.py:34:RuntimeWarning:从未等待协程'ClientSession.close' session.close() 未公开的客户会话 client_session: 未封闭的连接器 连接:['[(,15024.110107067)]','[(,15024.147785039)]','[(,15024.252375415)]','[(,15024.292646968)]','[(,15024.342368087)]','[ (,15024.466971983)]','[(,15024.602057745)]','[(,15024.837045568)]']] 连接器:
FWIW,这是main
在我尝试以上更改之前:
async def main(url):
async with aiohttp.ClientSession() as session:
print(f"Starting '{url}'")
html = await fetch(session, url)
print(f"'{url}' done")
Run Code Online (Sandbox Code Playgroud)
正确的方法是什么?我曾想过将URL列表传递给main,但无法使其以非顺序的方式工作。
Creating a client session outside of coroutine is a very dangerous idea
因为创建它时,它会绑定到当前循环。如果之后更改运行循环,它将挂起。但是,如果您足够仔细地使用它,则可以忽略它。相关文件。
对于我来说,我只是忽略了这个警告。但是也很容易克服它:
async def create_session():
return aiohttp.ClientSession()
session = asyncio.get_event_loop().run_until_complete(create_session())
Run Code Online (Sandbox Code Playgroud)
此外,您无需显式创建Task
对象,而只需执行此协程函数:
loop.run_until_complete(asyncio.gather(
*(main(url, session) for url in urls)
))
Run Code Online (Sandbox Code Playgroud)
最后,不要忘记close
是一个协程。您应该使用loop.run_until_complete(session.close())
close session
。
顺便说一句,如果您想创建一个类似异步的循环,可以参考我的另一个答案。
归档时间: |
|
查看次数: |
2599 次 |
最近记录: |