requests_html中arender()触发RuntimeError事件循环关闭问题求助
问题解决方案
原因分析
你的问题根源在于:AsyncHTMLSession的arender()方法会依赖自身管理的事件循环,而asyncio.run()在执行完毕后会自动关闭当前事件循环。当arender()尝试使用已经被关闭的循环时,就会抛出RuntimeError: Event loop is closed异常。
修复方案
以下两种方法都能解决问题,且保留你需要的asyncio.gather()批量执行能力:
方案1:用AsyncHTMLSession.run()托管整个异步流程
直接让AsyncHTMLSession管理事件循环,代替asyncio.run(),这样arender()能在正确的循环上下文中运行:
from requests_html import AsyncHTMLSession import asyncio async def check_state(session, url): r_inspection = await session.get(url) await r_inspection.html.arender() # 现在可以正常执行 # 这里添加你的页面解析逻辑 return f"处理结果:{url}" async def check_all(session): # 构造批量任务 tasks = [ check_state(session, "https://example.com"), check_state(session, "https://example.org"), check_state(session, "https://example.net") ] results = await asyncio.gather(*tasks) return results if __name__ == "__main__": a_session = AsyncHTMLSession() # 用a_session.run执行check_all,传入session实例 results = a_session.run(check_all, a_session) a_session.close() print(results)
方案2:手动创建并控制事件循环
如果坚持要用asyncio.run()的结构,可手动创建事件循环,避免asyncio.run()自动关闭循环的行为:
from requests_html import AsyncHTMLSession import asyncio async def check_state(session, url): r_inspection = await session.get(url) await r_inspection.html.arender() # 页面解析逻辑 return f"处理结果:{url}" async def check_all(): a_session = AsyncHTMLSession() tasks = [ check_state(a_session, "https://example.com"), check_state(a_session, "https://example.org") ] results = await asyncio.gather(*tasks) await a_session.close() return results if __name__ == "__main__": # 手动创建事件循环 loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) try: results = loop.run_until_complete(check_all()) finally: loop.close() print(results)
关键说明
AsyncHTMLSession内部已经维护了一个事件循环,arender()会依赖这个循环执行Chrome渲染的异步操作。asyncio.run()的设计是一次性运行异步函数,执行完毕后立即关闭循环,这和arender()的后台异步操作冲突。- 两种方案的核心都是让
arender()在未被关闭的事件循环上下文中完成执行。
内容的提问来源于stack exchange,提问作者Jensen Benny
相关产品推荐
相关产品推荐

