我想使用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

有什么问题吗?

如何解决?

推荐答案

asyncio.run()份文件说:

当另一个asyncio事件循环在同一线程中运行时,可以调用此函数.

在你的例子中,jupyter(IPython ≥ 7.0)已经在运行一个事件循环:

现在,您可以在IPython终端和笔记本电脑的顶层使用async/await,它应该 — 在大多数情况下 — "只是工作".将IPython更新为7+,将IPykernel更新为5+,你就可以开始比赛了.

因此,您不需要自己启动事件循环,而是可以直接调用await main(url),即使您的代码位于任何异步函数之外.

Jupyter / IPython

async def main():
    print(1)
    
await main()

Python (≥ 3.7)

import asyncio

async def main():
    print(1)
    
asyncio.run(main())

在你的代码中会给出:

url = ['url1', 'url2']
result = await main(url)

for text in result:
    pass # text contains your html (text) response

Caution

与IPython相比,Jupyter使用循环的方式有slight difference种.

Python-3.x相关问答推荐

海象表达可以放在方括号中而不是括号中吗?

Python gpsd客户端

从PYTHON中获取单行和多行的Rguar表达式

逐行比较2个Pandas数据帧,并对每一行执行计算

我正在try 从 10*3 矩阵中删除随机值并将其变为 10*2 矩阵

为什么空列表也能起作用?

删除浮点型数据集中每列重复值比例超过一定阈值的列

在Python中基于组/ID将两个数据帧进行映射,找出较接近的值

如何将日期时间索引写入日期类型的表?

Python rolling_corr 取消后,应该用什么方法来处理

从日志(log)文件中查找延迟最低的用户

python 3:如何判断一个对象是否是一个函数?

Python:pprint的模块错误,打印没有错误

Python - For 循环数百万行

str.format_map(mapping) 和 str.format 有什么区别

如何在 Python 中计算 cohen 的 d?

django - 值更改后自动更新日期

如何从 Python 3 导入 FileNotFoundError?

TypeError:只有整数标量数组可以转换为标量索引

什么是ANSI_X3.4-1968编码?