Django环境中运行requests_html的render函数触发「线程'Thread-1'无当前事件循环」RuntimeError的原因咨询
解决Django环境中使用requests-html.render()触发的RuntimeError问题
这个问题我之前做Django爬虫工具时也碰到过,刚好能给你理清楚原因和解决办法~
问题核心原因
你遇到的错误本质是线程与asyncio事件循环的匹配问题:
- 单独运行脚本时,代码在Python主线程执行,asyncio会自动创建默认事件循环,
requests-html的render()方法能顺利获取到循环并启动浏览器渲染。 - 但Django处理请求时,每个请求都在独立子线程(比如你看到的
Thread-1)中运行,这些子线程默认没有初始化asyncio事件循环。而requests-html的render()方法内部会调用asyncio.get_event_loop()获取当前线程的循环,找不到自然就抛出了RuntimeError。
快速解决方案
只需要在调用render()之前,手动在当前Django请求线程中创建并设置asyncio事件循环即可,修改后的代码如下:
import asyncio from requests_html import HTMLSession def analize(): session = HTMLSession() page = session.get('https://python.org/') # 关键步骤:为当前子线程创建并绑定事件循环 loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) # 现在可以正常调用render了 page.html.render() # 后续你的业务逻辑处理,比如提取页面内容 print(page.html.find('div.container', first=True).text)
如果担心资源占用,也可以在使用完后手动关闭循环:
# 在render执行完毕后添加 loop.close()
补充说明
如果你的Django项目用了异步视图(Django 3.1+支持),那情况会不一样——异步视图本身已经运行在事件循环中,直接调用render()通常不会触发这个错误。但从你的报错栈来看,你是在同步请求线程中运行代码,所以上面的方案最适用。
内容的提问来源于stack exchange,提问作者JhonyBony
相关产品推荐
相关产品推荐

