You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django使用requests_html调用render()报错无当前事件循环如何解决

问题原因
  • Django服务默认采用多线程模式处理请求,即使你没有主动创建线程,每个用户请求也会由独立的工作线程处理。
  • requests-html的render()方法底层依赖异步库pyppeteer,asyncio默认只会在主线程初始化事件循环,处理请求的子线程没有默认绑定的事件循环,因此调用render()时会抛出该异常。
解决方案

方案1:手动为当前线程绑定事件 loop

在调用render()前手动创建事件循环并绑定到当前线程,处理完成后关闭循环即可,改造成本最低,兼容传统WSGI部署模式,修改后的视图代码如下:

import asyncio
from django.http import HttpResponse
from django.core.validators import URLValidator
from requests_html import HTMLSession
from bs4 import BeautifulSoup
from .main import *

def index(request):
    url = request.GET.get('url')
    # 原有URL校验逻辑
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    
    session = HTMLSession()
    resp = session.get(url)
    resp.html.render()
    # 后续页面解析逻辑
    loop.close()
    return HttpResponse("解析完成")

方案2:使用异步视图

如果你的Django版本 >=3.1,可以直接采用异步视图搭配AsyncHTMLSession实现,原生支持事件循环,不需要手动创建:

from django.http import HttpResponse
from django.core.validators import URLValidator
from requests_html import AsyncHTMLSession
from bs4 import BeautifulSoup
from .main import *

async def index(request):
    url = request.GET.get('url')
    # 原有URL校验逻辑
    session = AsyncHTMLSession()
    resp = await session.get(url)
    await resp.html.render()
    # 后续页面解析逻辑
    return HttpResponse("解析完成")

注意该方案需要将项目部署在ASGI服务器(如Uvicorn、Daphne)上才能生效。

方案3:移除render()依赖

如果目标页面不需要执行JS就能获取到需要的内容,可以直接放弃render()调用,用BeautifulSoup直接解析resp.html.html的静态内容,完全避开asyncio相关的问题。

内容的提问来源于stack exchange,提问作者Javi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 10:03:00