简介:这份资源是适配 Playwright 1.56.1 的 Windows 离线浏览器包,面向在隔离网络或内网环境中开展自动化测试的开发者与测试团队,解决无法联网下载浏览器内核、依赖安装受阻的问题。压缩包共 663 个文件,约 415.03MB,以 pak 资源包、svg 图标、dll 动态库、js 脚本、png 图片及 exe 可执行文件为主,另含 json 配置、ini 与 dat 数据文件等,基本覆盖浏览器运行所需的完整组件。使用时将解压内容放入 %USERPROFILE%\AppData\Local\ms-playwright 目录即可被 Playwright 识别,省去在线拉取环节,也降低了外部下载带来的安全风险。目前已有 433 人学习下载,适合需要离线部署、搭建 CI/CD 自动化测试流水线或进行跨浏览器脚本调试的读者参考使用。
1. 为什么要在 Windows 上折腾 Playwright 离线浏览器包
在内网、隔离环境或 CI 流水线里跑 Playwright,最常翻车的不是脚本写错,而是浏览器二进制拉不下来。playwright install默认会去公网下载 Chromium、Firefox、WebKit 三件套,一旦网络受限,整个自动化链路直接卡死。Playwright 1.56.1 对应的离线浏览器包,本质就是把官方安装器要下载的那几个压缩包提前备好,放到本地目录,让安装器走本地路径完成解压和注册。它解决的是「环境无外网、但要用 Playwright 做端到端测试或爬取动态页面」这个具体问题,适合需要在 Windows 上做自动化测试、数据采集、页面回归的从业者。下面按「包长什么样 → 怎么放 → 怎么装 → 怎么验证 → 坑在哪」的顺序拆一遍,新手能照着复现,熟手能直接拿去改路径和版本号。
2. 离线包结构与版本对齐:先搞清目录再动手
2.1 离线包到底包含哪些文件
Playwright 的浏览器安装逻辑是:先读browsers.json确定每个浏览器的版本号和下载地址,再去下载对应压缩包,最后解压到%USERPROFILE%\AppData\Local\ms-playwright(Windows 默认路径)。离线包要做的,就是把这些压缩包按安装器期望的命名和目录结构放好。
以 1.56.1 为例,核心文件通常包括:
| 文件/目录 | 作用 | 典型大小 |
|---|---|---|
chromium-XXXX.zip | Chromium 主包 | 150MB 左右 |
chromium-headless-shell-XXXX.zip | 无头模式专用包 | 80MB 左右 |
ffmpeg-XXXX.zip | 录屏与视频依赖 | 2MB 左右 |
firefox-XXXX.zip | Firefox 包(可选) | 90MB 左右 |
webkit-XXXX.zip | WebKit 包(可选) | 70MB 左右 |
browsers.json | 版本映射表 | 几 KB |
这里的XXXX是 Playwright 内部维护的构建号,不是浏览器自身的版本号。很多人第一次拿到离线包会疑惑「为什么 Chromium 版本号对不上」,原因就在这里——安装器认的是构建号,不是 Chrome 的版本号。
提示:如果你只需要 Chromium 做无头采集,Firefox 和 WebKit 的包可以不放,安装时用
--with-deps之外的过滤参数跳过,能省一半体积。
2.2 版本对齐:为什么 1.56.1 不能混用别的包
Playwright 的 Node 包、Python 包、浏览器二进制三者之间有严格的版本绑定关系。1.56.1 的browsers.json里写死了它期望的构建号,如果你拿 1.55 的离线包去配 1.56.1 的库,安装器会报「expected build XXX but found YYY」或者干脆重新触发下载。
对齐方法很简单:在能联网的机器上装好同版本 Playwright,执行一次安装,然后去ms-playwright目录里看实际解压出来的文件夹名,把对应的 zip 收集起来。或者直接读node_modules/playwright-core/browsers.json,里面每个浏览器的revision字段就是你要匹配的构建号。
# 在联网机器上查看当前 Playwright 期望的浏览器构建号 node -e "const b=require('playwright-core/browsers.json'); b.browsers.forEach(x=>console.log(x.name, x.revision))"这段命令直接读browsers.json,把每个浏览器的名称和 revision 打出来。revision就是离线包文件名里那串数字,拿它去核对你的 zip 包名,对不上就说明版本不匹配,别急着往下走。
2.3 目录放置:安装器从哪里找离线包
Playwright 支持通过环境变量PLAYWRIGHT_BROWSERS_PATH指定浏览器安装目录,但它本身不直接读「离线包目录」。常见做法是两种:
第一种,把离线包解压后的文件夹直接放到ms-playwright下,跳过安装步骤。这种方式适合你已经有一台机器装好了,直接把整个ms-playwright目录拷到目标机器。缺点是跨机器时路径和注册信息可能不一致。
第二种,用PLAYWRIGHT_DOWNLOAD_HOST或本地文件服务模拟下载源。把离线包放在本地 HTTP 服务或文件路径下,让安装器以为自己在从「下载源」拉包。这种方式更干净,安装器会自己完成解压和注册。
# 方式二:用本地目录模拟下载源(Windows PowerShell) $env:PLAYWRIGHT_DOWNLOAD_HOST="file:///D:/playwright-offline" npx playwright install chromium这里PLAYWRIGHT_DOWNLOAD_HOST指向本地离线包所在目录,file:///是 Windows 下的文件协议写法,注意盘符后面是三个斜杠。执行后安装器会去这个目录找对应构建号的 zip,找到就解压,找不到才回退到公网。参数chromium表示只装 Chromium,需要全部就换成chromium firefox webkit。
3. 在 Windows 上完成离线安装:命令、参数与验证
3.1 前置条件:Node 版本与 Playwright 安装
离线包只解决浏览器二进制,Playwright 本身的 npm 包还是得先装。Windows 上建议 Node 18 以上,1.56.1 对 Node 16 的支持已经收窄。先建项目目录,初始化,再装指定版本:
mkdir pw-offline-demo && cd pw-offline-demo npm init -y npm install playwright@1.56.1 --save-exact--save-exact是为了锁死版本,避免^1.56.1在后续npm install时被升到 1.57 导致浏览器构建号对不上。这一步在离线环境里同样需要,因为 npm 包本身也得提前备好,可以用npm pack在联网机器上打成 tgz 再拷进来。
3.2 设置离线源并执行安装
假设离线包放在D:\playwright-offline,目录里直接是各个 zip 文件。执行:
# 设置离线下载源 set PLAYWRIGHT_DOWNLOAD_HOST=file:///D:/playwright-offline # 只安装 Chromium 和 headless shell npx playwright install chromium # 如果需要全部浏览器 npx playwright installset是 Windows CMD 的写法,PowerShell 用$env:。PLAYWRIGHT_DOWNLOAD_HOST的值必须是file:///开头加绝对路径,路径里不要有中文和空格,否则安装器解析 URL 时会出问题。执行后如果看到Downloading Chromium...然后迅速变成Installing...,说明它命中了本地文件,没有走公网。
安装完成后,浏览器会落在%USERPROFILE%\AppData\Local\ms-playwright。你可以去这个目录确认文件夹名和构建号是否与browsers.json一致。
3.3 验证:跑一个最小可复现脚本
装完不验证等于没装。写一个最小脚本,启动 Chromium,打开页面,截图,关闭:
// verify.js const { chromium } = require('playwright'); (async () => { // 启动 Chromium,headless 为 true 表示无头模式 const browser = await chromium.launch({ headless: true }); const page = await browser.newPage(); // 打开一个本地 HTML 或 about:blank 避免依赖外网 await page.goto('about:blank'); await page.setContent('<h1>offline ok</h1>'); // 截图保存到当前目录 await page.screenshot({ path: 'verify.png' }); await browser.close(); console.log('browser launched and screenshot saved'); })();chromium.launch的headless: true会走chromium-headless-shell包,如果你只装了主包没装 headless shell,这里会报chrome-headless-shell.exe doesn't exist。page.setContent直接注入 HTML,不依赖网络,适合隔离环境验证。截图成功说明浏览器二进制、依赖库、启动链路都通了。
node verify.js如果输出browser launched and screenshot saved且当前目录出现verify.png,离线安装就算完成。如果报错,先看错误里提到的路径,再去ms-playwright下核对文件夹是否存在。
3.4 参数速查:安装与启动常用项
| 参数/变量 | 作用 | 建议值 |
|---|---|---|
PLAYWRIGHT_DOWNLOAD_HOST | 指定下载源 | file:///D:/playwright-offline |
PLAYWRIGHT_BROWSERS_PATH | 指定浏览器安装目录 | 默认即可,跨盘时改 |
--save-exact | 锁定 npm 包版本 | 必加 |
headless | 是否无头启动 | 采集用 true,调试用 false |
channel | 指定浏览器通道 | 离线包一般不用 |
PLAYWRIGHT_BROWSERS_PATH如果改成相对路径,安装器会相对于当前工作目录解析,容易在不同终端里表现不一致,建议用绝对路径。channel是给系统已装 Chrome/Edge 用的,离线包场景下不要设,否则会绕过你准备的二进制。
4. 避坑与排查:离线安装最常见的五类翻车
4.1 报错chrome-headless-shell.exe doesn't exist
现象:脚本用headless: true启动时报找不到chrome-headless-shell.exe。
原因:1.56.1 把无头模式拆成了独立的chromium-headless-shell包,只装chromium主包不包含这个可执行文件。
解决:离线包里必须同时包含chromium-headless-shell-XXXX.zip,安装时不要只过滤chromium。或者启动时显式用channel: 'chromium'并设headless: false走主包,但这样会失去无头优势。
4.2 安装器仍然尝试联网
现象:设了PLAYWRIGHT_DOWNLOAD_HOST,但日志里还是出现公网域名。
原因:环境变量没生效,或者当前终端是 PowerShell 而你用了 CMD 的set语法;也可能是离线包里缺少对应构建号的 zip,安装器回退到默认源。
解决:先echo %PLAYWRIGHT_DOWNLOAD_HOST%(CMD)或echo $env:PLAYWRIGHT_DOWNLOAD_HOST(PowerShell)确认变量值。再核对 zip 文件名里的构建号与browsers.json是否一致。缺包就补包,别指望它自动跳过。
4.3 路径含中文或空格导致解压失败
现象:安装过程中报ENOENT或解压到一半中断。
原因:file:///URL 对中文和空格的处理不稳定,Windows 下尤其明显。
解决:离线包目录用纯英文、无空格路径,比如D:\pw-offline。如果必须放中文路径,改用本地 HTTP 服务(如python -m http.server)把目录暴露成http://127.0.0.1:8000,再把PLAYWRIGHT_DOWNLOAD_HOST指向它。
4.4 多版本 Playwright 共用同一浏览器目录
现象:机器上同时有 1.55 和 1.56.1 两个项目,装完后其中一个跑不起来。
原因:ms-playwright是共享目录,不同版本的构建号不同,文件夹名不同,但安装器可能因为缓存判断跳过安装。
解决:给不同版本设不同的PLAYWRIGHT_BROWSERS_PATH,比如D:\pw-browsers\1.56.1,项目启动脚本里带上这个变量。代价是占磁盘,但能彻底隔离。
4.5 杀毒软件拦截解压出的可执行文件
现象:安装成功,但启动浏览器时进程秒退,无日志。
原因:部分安全软件会把ms-playwright下的chrome.exe、headless_shell.exe当可疑文件隔离。
解决:把ms-playwright目录加入白名单,或者换一个非系统盘目录。排查时可以先临时关闭实时防护跑一次验证脚本,确认是拦截问题再配白名单。
5. 进阶:把离线包做成可复用的内部分发目录
单机装通只是第一步,团队里十几台机器都要用,就得把离线包整理成可复用的分发结构。我一般会按「版本号 + 平台」建目录,再配一个安装脚本,让新人一条命令搞定。
# 目录结构示例 # D:\pw-dist\ # ├── 1.56.1\ # │ ├── chromium-1148.zip # │ ├── chromium-headless-shell-1148.zip # │ ├── ffmpeg-1011.zip # │ └── browsers.json # └── install-pw.batinstall-pw.bat内容:
@echo off set PLAYWRIGHT_DOWNLOAD_HOST=file:///D:/pw-dist/1.56.1 set PLAYWRIGHT_BROWSERS_PATH=D:\pw-browsers\1.56.1 call npm install playwright@1.56.1 --save-exact call npx playwright install chromium echo done这个脚本把下载源、安装目录、npm 包版本三件事绑在一起,避免每个人环境不一致。PLAYWRIGHT_BROWSERS_PATH指向独立目录,和系统默认的AppData隔离,卸载时直接删目录,不留残留。
验证分发是否成功,不要只看安装日志,要跑一个带断言的脚本:
// assert.js const { chromium } = require('playwright'); const assert = require('assert'); (async () => { const browser = await chromium.launch({ headless: true }); const page = await browser.newPage(); await page.setContent('<div id="v">1.56.1</div>'); const text = await page.textContent('#v'); // 断言页面内容,确保渲染链路正常 assert.strictEqual(text, '1.56.1'); await browser.close(); console.log('assert passed'); })();assert.strictEqual比单纯截图更可靠,因为它验证了 DOM 解析和 JS 执行都正常。如果这一步过了,说明离线包不只是「装上了」,而是「能干活」。
从那以后我每次准备离线包,都会先在联网机器上跑一遍browsers.json导出,把构建号抄下来,再核对 zip 文件名,最后在目标机器上跑断言脚本。这套流程走下来,基本不会再遇到装完跑不起来的玄学问题。希望帮到你。
本文还有配套的精品资源,点击获取