Puppeteer 浏览器管理指南:@puppeteer/browsers 的 CLI 命令、编程式 API 与自定义下载源实战
本指南以 Puppeteer 仓库中独立子包
@puppeteer/browsers的 API 文档(docs/browsers-api/index.md)为主体,系统讲解如何通过 CLI 与编程式 API 统一管理 Chrome、Firefox、ChromeDriver 等浏览器与驱动的下载、安装、缓存与启动。读完你将掌握npx @puppeteer/browsers的全部常用命令、install/launch/computeExecutablePath等核心函数的真实用法,以及如何为内网镜像等场景编写自定义 Provider 下载源。文中所有结论均可在 packages/browsers 包源码与测试中得到验证。
一、@puppeteer/browsers 是什么
@puppeteer/browsers 是 Puppeteer 仓库中独立发布、独立版本号的一个 Node 子包,负责"下载与启动浏览器"(其 package.json 描述即 "Download and launch browsers")。它与 Puppeteer 主库解耦,既可被 Puppeteer 内部缓存、安装浏览器时调用,也可被任何脚本、CI 或工具链单独使用。
它聚焦解决一个高频工程问题:在不同平台(Linux / macOS / Windows × x64 / ARM)上,以确定性的版本下载并管理 Chrome for Testing、ChromeDriver、Chromium、Firefox、chrome-headless-shell 等可执行文件,并把可执行文件路径以与 Puppeteer 缓存兼容的目录结构暴露给上层调用方。
系统要求(System requirements)
- Node 版本:需满足该包
package.json中engines声明的版本。当前仓库中该包(version3.2.1)要求node >=22.12.0(见 packages/browsers/package.json)。 - Firefox 下载的解压工具依赖:
- Linux 构建产物为
.tar.gz/.tar.bz2,需要系统提供xz与bzip2工具; - macOS 构建产物为
.dmg,需要系统提供hdiutil。
- Linux 构建产物为
- Chrome 下载的解压工具依赖:
- Linux/macOS 需要
unzip; - Windows 需要
tar.exe。
- Linux/macOS 需要
若解压阶段失败,可优先排查这些系统工具是否可用。仓库测试目录中保留了 test.tar.xz、test.tar.bz2、test.zip 等夹具(见 packages/browsers/test/fixtures),对应解压逻辑可在 fileUtil.ts 中查看。
二、CLI:一条命令下载并管理浏览器
@puppeteer/browsers 提供开箱即用的 CLI。由于包的 bin 字段指向 lib/main-cli.js(见 packages/browsers/package.json),你可以直接用 npx 运行而无需事先安装:
# 若当前目录尚未安装该包,会临时安装并运行;若已安装则使用本地版本
npx @puppeteer/browsers --help
内置了针对每个子命令的 --help,是了解全部参数的第一手资料:
npx @puppeteer/browsers --help # 全部命令帮助
npx @puppeteer/browsers install --help # install 命令帮助
npx @puppeteer/browsers launch --help # launch 命令帮助
npx @puppeteer/browsers clear --help # clear 命令帮助
npx @puppeteer/browsers list --help # list 命令帮助
固定 npx 版本
npx 默认拉取注册表最新版本,可通过 @版本号 语法锁定:
# 总是使用注册表最新版
npx @puppeteer/browsers@latest --help
# 锁定某个具体版本
npx @puppeteer/browsers@2.4.1 --help
# 使用最新版并跳过 npx 的安装确认提示
npx --yes @puppeteer/browsers@latest --help
常用命令速览
clear:清空缓存目录中所有已安装浏览器(执行时会要求交互确认 yes/No,见 CLI.ts):
npx @puppeteer/browsers clear
list:列出缓存目录中所有已安装的浏览器,输出格式为 <browser>@<buildId> (<platform>) <executablePath>(对应实现见 CLI.ts):
npx @puppeteer/browsers list
install 的典型用法(browser@buildId 的定位参数解析逻辑见 CLI.ts):
# 下载与 Stable 频道对应的最新 Chrome for Testing 二进制
npx @puppeteer/browsers install chrome@stable
# 下载指定版本的 Chrome for Testing
npx @puppeteer/browsers install chrome@116.0.5793.0
# 下载指定 Milestone(大版本号) 下最新的 Chrome for Testing
npx @puppeteer/browsers install chrome@117
# 下载与 Canary 频道对应的最新 ChromeDriver
npx @puppeteer/browsers install chromedriver@canary
# 下载指定版本的 ChromeDriver
npx @puppeteer/browsers install chromedriver@116.0.5793.0
# 在 Ubuntu/Debian 上为 Chrome 安装浏览器二进制及所需系统依赖。
# 即使浏览器已装过也会尝试安装系统依赖;需要 root 权限。
npx puppeteer browsers install chrome --install-deps
install 的其它实用参数
从 CLI.ts 可以看到 install 还支持:
--platform <platform>:指定目标平台(choices 覆盖BrowserPlatform全部取值,例如linux、mac、mac-arm、win32、win64),默认自动探测当前系统。--path <dir>:指定下载与安装的根目录;目录结构与 Puppeteer 使用的缓存结构兼容。默认当前工作目录。--base-url <url>:指定下载镜像根地址(镜像场景下不必写自定义 Provider 也能替换下载源)。--format <fmt>:安装成功后打印的结果模板,支持占位符{{browser}}、{{buildId}}、{{path}}、{{platform}},默认{{browser}}@{{buildId}} {{path}}(实际替换逻辑见 CLI.ts)。--install-deps:是否尝试通过apt-get安装系统依赖,仅 Linux 上受支持且需要 root 权限(实现细节见 install.ts)。
launch 命令则用于直接启动已缓存或系统自带的浏览器:
# 从缓存启动指定版本 Chrome
npx @puppeteer/browsers launch chrome@115.0.5790.170
# 启动后传入自定义参数(用 -- 分隔)
npx @puppeteer/browsers launch chrome@115.0.5790.170 -- --version
# 以 detached 模式启动,分离子进程
npx @puppeteer/browsers launch chrome@115.0.5790.170 --detached
# --system:放弃缓存,改在系统安装位置中查找 Canary 版 Chrome
npx @puppeteer/browsers launch chrome@canary --system
# --dumpio:将浏览器 stdout/stderr 转发到当前终端
npx @puppeteer/browsers launch firefox@112.0a1 --dumpio
Known limitations
文档明确列出一个已知限制:launch 启动"系统浏览器"的能力只适用于 Chrome/Chromium。对其它浏览器(如 Firefox),需要先通过该缓存结构下载安装后再启动。
三、代理(Proxies)
库与 CLI 均会读取并遵守 HTTP_PROXY、HTTPS_PROXY 与 NO_PROXY 三个环境变量,但它们要真正生效,还需要额外安装 proxy-agent 依赖包(在 package.json 中被声明为可选 peerDependency):
npm install proxy-agent
装好后在既有代理环境中设置对应环境变量即可,无需修改任何代码。
四、调试:NODE_DEBUG 分级日志
要观察下载进度、安装步骤与启动参数等内部细节,使用 Node 内置的 NODE_DEBUG 环境变量启用 @puppeteer/browsers 的分级日志:
env NODE_DEBUG="puppeteer:browsers:*" npx @puppeteer/browsers install chrome@stable
可用的调试频道(与 debug.ts 中定义的 DEBUG_PREFIXES 对应):
puppeteer:browsers:cache:缓存目录读写等缓存操作日志;puppeteer:browsers:fileUtil:解压及其它文件工具日志;puppeteer:browsers:install:下载与安装进度日志(含Downloading <browser> <buildId> ...之类的进度条信息与耗时统计,见 install.ts);puppeteer:browsers:launcher:浏览器启动参数与进程状态日志(如Launching <path> <args>、Launched <pid>,见 launch.ts)。
需要更细粒度时可只开启单个频道,例如 NODE_DEBUG="puppeteer:browsers:launcher",减少无关噪音。
五、自定义 Provider:接入内网镜像等替代下载源
对于企业内网镜像、私有仓库或定制浏览器构建产物,@puppeteer/browsers 提供了 Provider(下载源提供者) 抽象。底层接口定义于 provider.ts,包含三个方法:
supports(options):判断该 Provider 是否支持某浏览器 + 平台组合;getDownloadUrl(options):返回下载地址;若无法解析版本可返回null,让调用方继续尝试下一个 Provider;getExecutablePath(options):返回解压后相对安装目录的可执行文件路径;getName():Provider 名称,用于日志与报错。
文档给出的 SimpleMirrorProvider 完整示例即实现上述接口,把下载 URL 拼到自定义镜像域名上,并按平台返回对应归档文件名与可执行文件相对路径:
import {
BrowserProvider,
DownloadOptions,
Browser,
BrowserPlatform,
} from '@puppeteer/browsers';
class SimpleMirrorProvider implements BrowserProvider {
constructor(private mirrorUrl: string) {}
supports(options: DownloadOptions): boolean {
return options.browser === Browser.CHROME;
}
getDownloadUrl(options: DownloadOptions): URL | null {
const {buildId, platform} = options;
const filenameMap = {
[BrowserPlatform.LINUX]: 'chrome-linux64.zip',
[BrowserPlatform.MAC]: 'chrome-mac-x64.zip',
[BrowserPlatform.MAC_ARM]: 'chrome-mac-arm64.zip',
[BrowserPlatform.WIN32]: 'chrome-win32.zip',
[BrowserPlatform.WIN64]: 'chrome-win64.zip',
};
const filename = filenameMap[platform];
if (!filename) return null;
return new URL(`${this.mirrorUrl}/chrome/${buildId}/${filename}`);
}
getExecutablePath(options: DownloadOptions): string {
const {platform} = options;
if (
platform === BrowserPlatform.MAC ||
platform === BrowserPlatform.MAC_ARM
) {
return 'chrome-mac/Chromium.app/Contents/MacOS/Chromium';
} else if (platform === BrowserPlatform.LINUX) {
return 'chrome-linux64/chrome';
} else if (platform.includes('win')) {
return 'chrome-win64/chrome.exe';
}
throw new Error(`Unsupported platform: ${platform}`);
}
}
随后把它传入 install API 的 providers 数组即可:
import {install} from '@puppeteer/browsers';
const customProvider = new SimpleMirrorProvider('https://internal.company.com');
await install({
browser: Browser.CHROME,
buildId: '120.0.6099.109',
platform: BrowserPlatform.LINUX,
cacheDir: '/tmp/puppeteer-cache',
providers: [customProvider],
});
Provider 链与回退机制
多个 Provider 可以链式组合,按数组顺序依次尝试,直到某一个成功为止;DefaultProvider(默认下载源)会被自动追加为最终兜底。真实的尝试、失败收集与回退逻辑见 install.ts:代码会依次调用每个 Provider 的 supports → getDownloadUrl,拿到有效 URL 后执行下载与解压;全部失败时抛出汇总了每个 Provider 报错信息的 All providers failed for ... 异常。DefaultProvider 的实现(对所有浏览器都返回 supports = true,并根据 baseUrl 拼装官方下载地址)见 DefaultProvider.ts。
⚠️ 重要提醒:文档与源码都反复强调——自定义 Provider 不受 Puppeteer 官方支持。使用方必须自行承担:二进制与 Puppeteer 期望的结构是否兼容、浏览器能否正常启动与工作、上游源变化后的持续适配,以及多平台混用不同来源时的版本一致性。Puppeteer 仅对默认下载的 Chrome for Testing 二进制做测试与兼容性保障。
六、编程式 API:在代码中管理浏览器生命周期
除了 CLI,该包导出一整套编程式 API(入口聚合见 packages/browsers/src/main.ts)。API 文档建议直接阅读包的 test 目录获取可直接运行的用法示例,对应测试代码位于 packages/browsers/test/src,按浏览器分目录组织了 install、launch、CLI、缓存与卸载测试(例如 chrome/install.test.ts、chrome/launch.test.ts、list.test.ts、installWithProviders.test.ts)。
安装:install / canDownload / uninstall / getInstalledBrowsers
import {
install,
canDownload,
uninstall,
getInstalledBrowsers,
Browser,
} from '@puppeteer/browsers';
// 下载并解压(返回 InstalledBrowser 实例)
const browser = await install({
browser: Browser.CHROME,
buildId: '116.0.5793.0',
cacheDir: '/tmp/puppeteer-cache',
// platform: 可选,默认自动探测
// downloadProgressCallback: 'default' 会显示进度条,也可传自定义回调
});
// 预先探测:给定版本当前是否可下载(会向服务端发起 HEAD 请求)
const ok = await canDownload({
browser: Browser.CHROME,
buildId: '116.0.5793.0',
cacheDir: '/tmp/puppeteer-cache',
});
// 卸载指定构建
await uninstall({
browser: Browser.CHROME,
buildId: '116.0.5793.0',
cacheDir: '/tmp/puppeteer-cache',
});
// 列出缓存中的全部浏览器
const installed = await getInstalledBrowsers({cacheDir: '/tmp/puppeteer-cache'});
install 的完整选项定义于 install.ts,值得留意的参数包括:
unpack: false时可只下载归档文件而不解压,函数返回归档的绝对路径(对应 API 文档中的第二个重载);baseUrl:指定下载源根地址;expectedHash:期望的 SHA-256 校验和,提供后下载文件不匹配将导致安装失败;installDeps:是否安装系统依赖(仅 Chrome + Debian/Ubuntu + root);buildIdAlias:为实际buildId维护一个本地别名(如canary),便于launch时引用。
安装完成后,缓存目录内部结构为 rootDir/<browser>/<platform>-<buildId>/...,其中 .metadata 文件记录别名与可执行文件路径映射(见 Cache.ts 中的目录结构注释与读写逻辑)。
启动:launch 与进程管理
import {launch} from '@puppeteer/browsers';
const proc = launch({
executablePath: '/tmp/puppeteer-cache/chrome/linux-116.0.5793.0/chrome',
// pipe/dumpio/args/env/detached/handleSIGINT 等均为可选
detached: true,
});
// 等待浏览器输出中匹配指定正则的行,典型用于捕获
// CDP / WebDriver BiDi 的 ws:// 端点地址
const wsEndpoint = await proc.waitForLineOutput(
/^DevTools listening on (ws:\/\/.*)$/,
30000,
);
// 读取浏览器最近的 stdout/stderr 日志
console.log(proc.getRecentLogs());
// 关闭或强杀进程
await proc.close();
Process 类(launch.ts)在构造时即通过 child_process.spawn 拉起浏览器进程,并封装了日志行缓冲(上限 1000 行)、waitForLineOutput 等待匹配、getRecentLogs、kill(Linux 下按进程组 SIGKILL、Windows 下走 taskkill /pid <pid> /T /F)与 close 等能力。与之配套的两个正则常量供上层解析自动化端点:
CDP_WEBSOCKET_ENDPOINT_REGEX:匹配DevTools listening on (ws://...)WEBDRIVER_BIDI_WEBSOCKET_ENDPOINT_REGEX:匹配WebDriver BiDi listening on (ws://...)
进程对象默认处理父进程的 SIGINT(触发 kill 并 exit(130))、SIGTERM/SIGHUP(触发优雅 close),确保父进程退出时不会遗留孤儿浏览器进程。
路径计算:computeExecutablePath 与 computeSystemExecutablePath
computeExecutablePath 根据缓存根目录、浏览器、平台与 buildId 计算可执行文件绝对路径;当 cacheDir 传 null 时返回相对解压目录的相对路径(如 ./chrome-linux64/chrome)。可执行文件路径若存在于 .metadata(自定义 Provider 场景)则优先读取,否则按内置的 executablePathByBrowser 各浏览器目录规则计算(见 Cache.ts)。
computeSystemExecutablePath 则根据发布频道在系统已知安装位置查找 Chrome,找不到时抛出包含候选路径列表的错误;第二个参数 validatePath 传 false 时可跳过存在性校验、直接返回首个候选路径(见 launch.ts)。
版本解析与其它工具函数
CLI 之所以能接受 stable/canary/117 等别名或里程碑号,是因为安装前先经过 resolveBuildId(browser, platform, tag) 解析为精确 buildId。以 chrome@117 为例,它会解析为 117 里程碑下最新可用的完整版本号后再下载(CLI 中的调用链见 CLI.ts)。API 文档中列出的其它重要导出还有:
Browser、BrowserPlatform、BrowserTag、ChromeReleaseChannel枚举:分别表示受支持的浏览器、平台-架构组合、发布渠道标签与 Chrome 发布频道(API 页面分别为 browsers.browser.md、browsers.browserplatform.md、browsers.browsertag.md、browsers.chromereleasechannel.md);detectBrowserPlatform():自动探测当前系统对应的下载平台标识;getDownloadUrl(browser, platform, buildId, baseUrl?):直接返回某浏览器某版本在某平台下的官方归档下载 URL;getVersionComparator(browser):获取按版本语义排序的比较器,用于对版本列表排序;resolveDefaultUserDataDir(browser, platform, channel):返回指定频道预期的默认用户数据目录(不检查目录是否存在);createProfile、buildArchiveFilename:配置概要创建与标准归档文件名工具;TimeoutError:等待超时时抛出的专用错误类型。
完整 API 分类索引可在 docs/browsers-api/index.md 的 Classes / Enumerations / Functions / Interfaces / Variables 五张表中逐项查阅,每项都链接到独立的 API 说明页(如 install、launch、BrowserProvider 等)。
七、总结与推荐实践
综合文档与源码,给出几条可直接落地的使用建议:
- CI 中固定版本:用
npx @puppeteer/browsers@<版本>锁定工具版本,配合chrome@<buildId>(建议用精确 buildId 保证可复现性),避免"今天能装、明天装不上"的漂移问题。 - 共享缓存目录:通过
--path(CLI)或cacheDir(API)让多个任务共享同一缓存根目录,其结构与 Puppeteer 主库缓存兼容,可避免重复下载。 - 内网/镜像环境:优先尝试
--base-url指向公司镜像;若镜像目录结构特殊,再实现BrowserProvider并链入providers数组,同时做好多 Provider 回退与二进制兼容性自测。 - 排障先开日志:安装失败先设
NODE_DEBUG="puppeteer:browsers:install"(或puppeteer:browsers:*)定位下载/解压环节,再检查对应平台的系统工具(unzip/xz/bzip2/hdiutil/tar.exe)是否齐全。 - 进程清理交给 Process:在代码中以编程方式启动浏览器后,始终通过
Process.close()/kill()收尾,其信号处理逻辑(Windowstaskkill、Linux 进程组SIGKILL)能最大程度避免残留进程。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0626
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00