我想使用asyncio获得网页html。
我在jupyter notebook中运行以下代码:
import aiofiles
import aiohttp
from aiohttp import ClientSession
async def get_info(url, session):
resp = await session.request(method="GET", url=url)
resp.raise_for_status()
html = await resp.text(encoding='GB18030')
with open('test_asyncio.html', 'w', encoding='utf-8-sig') as f:
f.write(html)
return html
async def main(urls):
async with ClientSession() as session:
tasks = [get_info(url, session) for url in urls]
return await asyncio.gather(*tasks)
if __name__ == "__main__":
url = ['http://huanyuntianxiazh.fang.com/house/1010123799/housedetail.htm', 'http://zhaoshangyonghefu010.fang.com/house/1010126863/housedetail.htm']
result = asyncio.run(main(url))
但是,它返回RuntimeError: asyncio.run() cannot be called from a running event loop
有什么问题吗?
怎么解决呢?
6条答案
按热度按时间yzxexxkh1#
asyncio.run()
文档说明:当另一个asyncio事件循环正在同一线程中运行时,不能调用此函数。
在本例中,jupyter(IPython ≥ 7.0)已经在运行一个事件循环:
现在,您可以在IPython终端和笔记本电脑的顶层使用async/await, 在大多数情况下 ,它应该 “正常工作”。将IPython更新到版本7+,将IPykernel更新到版本5+,您就可以开始比赛了。
因此,您不需要自己启动事件循环,而是可以直接调用
await main(url)
,即使您的代码位于任何异步函数之外。Jupyter(IPython ≥ 7.0)
Python ≥ 3.7且IPython〈7.0
在您的代码中,将给予:
注意事项
与IPython相比,Jupyter使用循环的方式略有不同。
uyto3xhc2#
为了补充
cglacet
的答案-如果你想检测一个循环是否正在运行并自动调整(即在现有循环上运行main()
,否则运行asyncio.run()
),这里有一个片段可能会被证明是有用的:dwbf0jvd3#
就用这个:
https://github.com/erdewit/nest_asyncio
biswetbf4#
结合Pankaj Sharma和Jean Monet的方法,我编写了以下代码片段,它充当asyncio.run(语法略有不同),但也适用于Jupyter笔记本。
用法:
b4lqfgs45#
我发现
unsync
包对于编写在Python脚本和Jupyter REPL中表现相同的代码很有用。0aydgbwb6#
正如cglacet提到的,文档中说
当另一个asyncio事件循环正在同一线程中运行时,不能调用此函数。
您可以使用其他线程,即-