直接结论:用 lighthouse cli 配合 python 的 subprocess 调用最稳,别试图用纯 python 重实现 lighthouse。因为 lighthouse 依赖 chromium 实例、完整渲染管线、performance api 和 devtools 协议,selenium 或 requests 无法获取 fid、lcp、tbt 等真实交互指标,结果偏差大;常见错误包括模块未安装、chrome 启动失败、performance 分数为 0;必须全局安装 node.js 和 lighthouse,严格用 subprocess.run() 控制超时、输出与退出码,并避免复用调试端口或并发过高导致资源耗尽。

直接结论:用 lighthouse CLI 配合 Python 的 subprocess 调用最稳,别试图用纯 Python 重实现 Lighthouse。
为什么不能用 requests + selenium 自己搭 Lighthouse 流程?
Lighthouse 不是普通 HTTP 接口服务——它依赖 Chromium 实例、完整的渲染管线、Performance API 和 DevTools 协议。自己用 selenium 模拟页面加载、采集指标,根本拿不到 FID、LCP、TBT 这类需要真实用户交互路径的指标,结果和官方 CLI 差距极大。
常见错误现象:Runtime error: Cannot find module 'lighthouse'(没全局安装)、Chrome failed to start: exited abnormally(缺少 --no-sandbox 或权限)、生成的报告里 performance 分数为 0(没加 --throttling-method=devtools)。
- 必须全局安装 Node.js 和
lighthouse:npm install -g lighthouse - 确保系统有可执行的 Chromium/Chrome(
lighthouse默认找chrome,Linux 上常需指定--chrome-flags="--headless --no-sandbox") - 不建议用
pyppeteer或playwright封装 Lighthouse——它们不兼容 Lighthouse 的内部协议
怎样用 Python 安全调用 lighthouse 并捕获结果?
核心是用 subprocess.run() 启动 CLI,并严格控制超时、输出路径和退出码。Lighthouse 成功时返回 0,失败时返回非 0(比如 URL 无法访问、超时、Chrome 崩溃),必须检查 result.returncode。
示例关键参数:
import subprocess
import json
<p>cmd = [
"lighthouse",
"<a href="https://www.php.cn/link/b05edd78c294dcf6d960190bf5bde635">https://www.php.cn/link/b05edd78c294dcf6d960190bf5bde635</a>",
"--output", "report.json",
"--output", "report.html",
"--quiet",
"--chrome-flags=--headless --no-sandbox",
"--throttling-method=devtools",
"--emulated-form-factor=desktop",
"--preset=desktop",
"--report-only-audit=first-contentful-paint,interactive,largest-contentful-paint",
"--timeout=120"
]</p><p>result = subprocess.run(cmd, capture_output=True, text=True, timeout=180)
if result.returncode != 0:
print("Lighthouse failed:", result.stderr)</p><h1>处理错误:可能是网络不通、页面 JS 报错、Chrome 启动失败</h1><p>else:
with open("report.json") as f:
data = json.load(f)
score = data["categories"]["performance"]["score"] * 100</p>
-
--quiet关键:关闭冗余日志,避免 stdout 干扰解析 -
--timeout=120和subprocess.run(..., timeout=180)要配合——前者是 Lighthouse 内部超时,后者是 Python 层兜底 -
--report-only-audit=...可大幅缩短运行时间,但会跳过 Accessibility / SEO 等审计项 - 不要用
shell=True,尤其在拼接用户输入的 URL 时,有命令注入风险
如何批量测试多个 URL 并避免 Chrome 实例堆积?
Lighthouse 每次运行都会启动新 Chrome 实例,不显式关闭会导致内存泄漏、端口占用、后续调用失败。CLI 默认行为是“用完即走”,但若加了 --chrome-flags="--remote-debugging-port=9222" 就必须手动管理。
- 绝对不要复用同一个
--remote-debugging-port;每次运行用随机端口或让 Lighthouse 自选(默认行为) - 批量测试时,每个 URL 单独调用
subprocess.run(),不要用subprocess.Popen手动维护进程 - Linux/macOS 下注意 ulimit:并发太多会触发
Too many open files,建议用concurrent.futures.ThreadPoolExecutor控制并发数 ≤3 - Windows 上遇到
Access is denied错误,大概率是杀毒软件拦截了 Chrome 子进程,临时禁用或加白名单
真正麻烦的是 Lighthouse 的非确定性——同一 URL 在不同机器、不同 Chrome 版本、不同系统负载下,LCP 可能浮动 ±200ms。做基准测试必须固定环境:统一 Chrome 版本(用 --chrome-binary 指向特定路径)、关闭后台程序、禁用浏览器扩展、用 --throttling-method=devtools 而非 simulate。否则数据不可比。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











