Ubuntu22.04下Flask调用Playwright脚本报错:Connection closed while reading from the driver
解决Flask+Nginx部署下Playwright连接中断问题
可能的原因及排查步骤
1. 权限问题(最常见)
直接运行脚本用的是当前用户,但Nginx/Flask通常以www-data用户运行,该用户可能没有Playwright浏览器或驱动的访问权限:
- 测试
www-data能否运行Playwright基础代码:
如果报错,说明权限不足,执行以下命令给sudo -u www-data python3 -c "from playwright.sync_api import sync_playwright; p=sync_playwright().start(); p.stop()"www-data安装专属的Playwright浏览器:sudo -u www-data playwright install
2. 环境变量/路径不匹配
直接执行脚本时的环境变量和Flask运行时的不一致,导致找不到Playwright资源:
- 在Flask代码中手动指定浏览器安装路径:
from playwright.sync_api import sync_playwright import os def run_script(): # 替换成你当前用户下的Playwright浏览器缓存路径,可通过`playwright install --help`查看默认路径 os.environ["PLAYWRIGHT_BROWSERS_PATH"] = "/home/your_username/.cache/ms-playwright" playwright = sync_playwright().start() # 后续业务代码... playwright.stop() - 或者在Flask启动脚本中同步环境变量,确保和直接执行时一致。
3. 系统资源限制不足
www-data用户的文件描述符或内存限制过低,导致Playwright启动失败:
- 修改系统限制,编辑
/etc/security/limits.conf,添加:www-data soft nofile 65535 www-data hard nofile 65535 - 重启Nginx和Flask服务生效:
sudo systemctl restart nginx sudo systemctl restart your_flask_service
替代方案
异步任务队列(推荐)
用Celery将Playwright任务剥离到独立worker执行,避免Flask进程阻塞:
- 安装Celery和消息中间件(比如Redis)
- 定义Celery任务:
# tasks.py from celery import Celery from playwright.sync_api import sync_playwright celery = Celery('tasks', broker='redis://localhost:6379/0') @celery.task def run_playwright_task(): playwright = sync_playwright().start() # 业务代码... playwright.stop() return "任务完成" - Flask路由中提交任务:
from flask import Flask from tasks import run_playwright_task app = Flask(__name__) @app.route('/trigger-task') def trigger(): task = run_playwright_task.delay() return f"任务已提交,ID: {task.id}"
异步Playwright+Flask异步路由
Flask 2.0+支持异步路由,配合Playwright异步API:
from flask import Flask from playwright.async_api import async_playwright app = Flask(__name__) @app.route('/run-playwright') async def run_playwright(): async with async_playwright() as p: browser = await p.chromium.launch() page = await browser.new_page() await page.goto("https://example.com") # 业务操作... await browser.close() return "执行成功"
内容的提问来源于stack exchange,提问作者Suren Gunaseelan
相关产品推荐
相关产品推荐

