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

在Django中用pyppeteer生成PDF报错:信号仅在主解释器主线程生效

解决Django中使用pyppeteer生成PDF的报错问题

问题分析

你遇到的两个错误本质是Django线程模型与pyppeteer异步运行机制的冲突:

  • signal only works in main thread of the main interpreter:pyppeteer启动浏览器时需要处理系统信号,而Django的请求处理线程并非主线程,信号只能在主线程中处理,因此触发该错误。
  • This event loop is already running:尝试在Django线程中手动调用run_until_complete时,该线程可能已存在活跃事件循环,导致重复运行报错。

解决方案

将pyppeteer的异步任务放到独立线程中执行,让该线程成为自身主线程以处理信号,同时避免与Django的事件循环冲突。修改后的views.py代码如下:

from pyppeteer import launch
import asyncio
from threading import Thread
from django.http import HttpResponse

async def main():
    browser = await launch()
    page = await browser.newPage()
    await page.goto("https://python.org")
    await page.waitFor(1000)
    await page.pdf({"path": "python.pdf"})
    await browser.close()

def run_async_task(func):
    # 创建新的事件循环并运行异步任务
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    loop.run_until_complete(func())
    loop.close()

def generate_pdf(request):
    print("Starting...")
    # 在独立线程中执行异步任务
    thread = Thread(target=run_async_task, args=(main,))
    thread.start()
    thread.join()
    print("PDF has been taken")
    return HttpResponse("PDF has been generated")

额外建议

生成PDF属于耗时操作,直接在请求线程中等待完成会导致请求阻塞,影响用户体验。建议使用异步任务队列(如Celery)将PDF生成任务后台化,请求仅负责触发任务并返回状态,后续再通过其他方式获取生成好的PDF文件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 23:04:59