Browserless 深度研究报告
> 一句话版本:Browserless 是一个让你在 Docker 里跑浏览器(Chrome/Firefox/WebKit),通过 API 远程调用的服务。你不用在自己服务器上装浏览器,也不用管 Puppeteer/Playwright 的生产环境问题——它帮你管理浏览器实例的生命周期、并发、排队和资源监控,你只管写业务代码。开源免费,做大了可以买云服务。
- 来源: https://github.com/browserless/browserless
- 官网: https://www.browserless.io/
- 文档: https://docs.browserless.io/
- 版本: v2.48.0(2026年4月)
- 研究日期: 2026-04-28
一、这是什么?
Browserless 本质上是一个 Browser-as-a-Service 的中间层——它把 Puppeteer/Playwright 这些浏览器自动化库封装成 HTTP/WebSocket API,通过 Docker 容器化部署,让开发者可以远程调用浏览器能力,而不用自己管理浏览器实例。
用它的方式很简单:
// 本地 Puppeteer
const browser = await puppeteer.launch();
// 换成 Browserless(只需改一行)
const browser = await puppeteer.connect({
browserWSEndpoint: 'ws://localhost:3000',
});
和直接用 Puppeteer/Playwright 的区别:你只连接到一个运行在 Docker 里的浏览器服务,不用在应用代码里嵌一个浏览器进程。浏览器进程崩溃不会导致你的服务崩溃——架构上彻底分离。
二、代码架构深度分析
2.1 技术栈
| 层级 | 技术 | 说明 |
|---|---|---|
| 语言 | TypeScript 6.0 | 纯 TS 项目,没有 JS 混用 |
| 运行时 | Node.js >= 24 | 紧跟最新 LTS |
| HTTP 服务器 | 原生 Node `http` 模块 | **没有用 Express/Fastify**,自己实现了一套 |
| 并发控制 | `queue` 包 | 轻量级任务队列,自己包裹了限流逻辑 |
| Schema 校验 | `joi` | 路由级别的请求 body/query 校验 |
| 浏览器库 | `playwright-core` + `puppeteer-core` | 同时支持两套生态 |
| 反检测 | `puppeteer-extra-plugin-stealth` | 内置 Stealth 插件 |
| 路由匹配 | `micromatch` | glob 模式匹配路径 |
| 监控 | `systeminformation` | CPU/内存健康检查 |
| 构建 | tsc + esbuild | TypeScript 编译 + esbuild 辅助 |
2.2 核心架构图
┌──────────────┐
│ Client │
│ (Puppeteer / │
│ Playwright) │
└──────┬───────┘
│ WebSocket / HTTP
┌──────▼───────┐
│ HTTP Server │ ← 原生 Node http,无框架
│ (server.ts) │
└──────┬───────┘
│
┌──────▼───────┐
│ Router │ ← micromatch 模式匹配
│ (router.ts) │
└──────┬───────┘
│
┌────────────┼────────────┐
│ │ │
┌──────▼─────┐ ┌───▼────┐ ┌────▼─────┐
│ Limiter │ │ Token │ │ Hooks │
│(并发/排队) │ │(鉴权) │ │(生命周期)│
└──────┬─────┘ └────────┘ └──────────┘
│
┌──────▼──────┐
│ BrowserMgr │ ← 按请求获取/释放浏览器
│ (browsers/) │
└──────┬──────┘
│
┌──────┴──────────┐
│ CDP / Playwright │
│ Chrome/Firefox/ │
│ Edge/WebKit │
└─────────────────┘
2.3 关键模块分析
`src/index.ts` — 入口
极简的启动脚本。创建 Browserless 实例,调用 start(),然后注册一堆信号处理器(SIGTERM, SIGINT, SIGHUP, SIGUSR2),优雅关闭所有子模块。没有复杂的 CLI 参数解析。
`src/browserless.ts` — 主类(核心)
这是最值得看的文件。它负责:
- 自动发现路由:扫描
src/routes/目录下的 TypeScript 文件,自动加载为 HTTP 或 WebSocket 路由 - 浏览器实例管理:加载所有已安装的 Playwright 版本,检测 binary 位置,注册内部浏览器类型(ChromiumCDP, ChromeCDP, EdgeCDP, FirefoxPlaywright 等)
- 指标持久化:定时保存运行指标到文件(每 5 分钟)
- ARM64 兼容:自动过滤不支持的浏览器(Chrome/Edge 在非 macOS ARM64 上不可用)
亮点:依赖注入友好——所有子模块都可以通过构造函数注入,方便测试和覆盖。
`src/server.ts` — HTTP 服务器
自己手写的 HTTP 服务器,没有用 Express。
- 同时处理
request(HTTP)和upgrade(WebSocket)事件 - 非 WebSocket 的 upgrade 请求(如 h2c)降级为 HTTP 处理
- CORS 支持(glob 匹配 origin)
- GET 请求通过
?body=...参数支持 POST body(兼容旧用法) - 请求校验:JSON body 解析 + Joi schema 校验
- Token 鉴权:Bearer token 或 query param 都支持
`src/router.ts` — 路由
基于 micromatch 的 glob 模式匹配,不是正则也不是固定路径。
- 按 method + path + content-type + accept 多重条件匹配
- 自动包裹 BrowserHTTPRoute:请求进来时从 BrowserManager 获取浏览器实例,请求完成后归还
- 支持并发控制:路由可以选择由 Limiter 包装,自动排队+超时
`src/limiter.ts` — 并发控制
基于 queue 包的实现,不是 Redis 也不是消息队列,完全进程内。
- 可配置 concurrent + queued 两个参数
- 健康检查前置:CPU/内存过载直接拒绝
- 事件钩子:success → 记指标,timeout → 记超时+webhook,error → 记错误+webhook
- 运行时动态配置:监听 Config 事件,concurrency/queue/timeout 可热更新
- 每完成一个任务走
hooks.after(),方便外部集成
`src/browsers/` — 浏览器定义
分为 CDP 和 Playwright 两套:
- CDP 系:ChromeCDP, ChromiumCDP, EdgeCDP — 通过 Chrome DevTools Protocol 通信
- Playwright 系:ChromiumPlaywright, FirefoxPlaywright, WebKitPlaywright, EdgePlaywright — 通过 Playwright API
功能差异:CDP 和 Playwright 路由不完全重叠,比如 /devtools 端点只在 CDP 浏览器上有。
路由系统
每个浏览器下基本都有这些端点:
/scrape— 抓取页面内容/pdf— 生成 PDF/screenshot— 截图/functions— 在浏览器上下文中执行 JavaScript/download— 下载文件/playwright— Playwright WebSocket 连接(供 Playwright 客户端连接)/devtools— CDP WebSocket 连接(供 Puppeteer 等连接)/config— 运行时配置
每个路由文件独立定义 method、path、accept content-type、body schema、auth 需求等。
三、亮点与槽点
👍 做的好的
1. 干净的分层架构 — 不依赖 Express/Fastify,自己实现的 Router 非常清晰。依赖注入让测试友好。
2. 双生态兼容 — 同时支持 Puppeteer 和 Playwright,CDP 和 Playwright 协议互不干扰。还捆绑多个 Playwright 版本(1.55-1.59)。
3. 进程级并发控制 — Limiter 代码干净利落,基于 queue 包实现,该有的功能都有(排队、超时、健康检查、动态配置)。
4. ARM64 支持 — 在 Apple Silicon 上表现良好,Edge/Chrome 不可用时自动跳过。
5. 零框架依赖 — 手写 HTTP 服务器,代码量不大但功能完整,可控性高。
6. 指标系统完善 — 内置运行指标采集 + 持久化,方便做容量规划。
👎 可以改进的
1. SSPL 许可证 — 与 MongoDB 相同,非商业免费但商业自托管需要额外买许可。白嫖友好,大厂劝退。
2. 纯进程内队列 — Limiter 基于 queue 包,不是 Redis/PG 后端,多实例部署时需要额外的负载均衡层。没有跨节点的队列协调。
3. HTTP 服务器手写虽然干净,但缺失中间件生态 — 没有 Express/Fastify 的插件体系,出问题得自己修。
4. Config 系统全靠环境变量 — 没有 YAML/JSON 配置文件,大量环境变量管理起来挺痛苦的。
5. 测试覆盖率 — spec 文件不多(limiter.spec.ts, metrics.spec.ts, utils.spec.ts 等),核心的 browserless.ts 和 server.ts 测试覆盖明显不足。
6. 依赖版本激进 — Node >= 24,部分还在 RC 阶段,自部署需要很新的环境。
四、与竞品对比
| Browserless | [Browserbase](https://browserbase.com) | Hyperbrowser | Playwright 原生 | |
|---|---|---|---|---|
| **开源** | ✅ SSPL | ❌ 闭源 | ❌ 闭源 | ✅ Apache 2.0 |
| **自托管** | ✅ Docker | ❌ | ❌ | 需要自己搭 |
| **反检测** | BrowserQL (付费) | 原生内置 | 内置 | 无 |
| **MCP 支持** | ✅ | ✅ | ✅ | ❌ |
| **AI 集成** | ✅ smart-scrape/crawl | ✅ | ✅ | ❌ |
| **多浏览器** | Chrome/Firefox/Edge/WebKit | Chromium | Chromium | 全支持 |
| **付费模式** | SaaS + Enterprise 自托管 | SaaS 仅云 | SaaS 仅云 | 免费 |
Browserless 最大的差异化在于开源 + 可自托管。Browserbase 和 Hyperbrowser 都是纯 SaaS,代码不可见。对于想自己控制生产环境的团队,Browserless 几乎是唯一选择。
五、定价与商业许可
Browserless 的价格分两大块:Cloud(云托管) 和 Enterprise(商业许可 + 自托管)。
5.1 Cloud 价格(年付,省 ~30%)
| 套餐 | 月费 | 并发数 | Units/月 | 超额单价 |
|---|---|---|---|---|
| **Free** | $0 | 2 | 1k | — |
| **Prototyping** | $25 | 10 (+5 burst) | 20k | $0.0020/unit |
| **Starter**(热门) | $140 | 40 (+10 burst) | 180k | $0.0017/unit |
| **Scale** | $350 | 100 (+20 burst) | 500k | $0.0015/unit |
| **Enterprise** | 议价 | 数百-数千 | 百万级 | 定制 |
> 1 Unit = 30 秒浏览器连接。超过 30 秒每 30 秒累加 1 Unit。驻留代理 6 Units/MB,验证码 10 Units/次。
5.2 商业许可
商业许可是 Enterprise 套餐的一部分,不自带,需要联系销售(sales@browserless.io)单独议价。
| 场景 | 费用 |
|---|---|
| 个人开发 / 非商业 | **免费**(SSPL 允许) |
| 商用自托管(闭源) | **需买商业许可**(Enterprise 议价) |
| 直接用云 | **按套餐付费**($25-$350+/月) |
Enterprise 商业许可包含:
- 商业许可证(允许闭源自托管)
- 私有部署(你自己的服务器或云账号)
- GPU 基础设施
- SSO 集成
- 自定义代理限制 + 地理定位
- 持久化缓存和 Cookie
- 视频支持 + 设置协助
- 专属技术客户经理
- Slack 专享支持
- 用户角色管理
无公开标价,价格取决于并发量、是否要 GPU、部署规模等。
5.3 小结
如果场景不敏感,直接用云套餐更省心(Free 够开发测试,Prototyping $25 对小项目够用)。如果需要生产自托管且闭源,必须走 Enterprise 谈商业许可。
六、与我们项目的关系
Jay 的 OpenClaw 项目 在多个地方可以用到 Browserless:
1. 本 Agent 的 web_fetch fallback:目前 web_fetch 失败后走 browser,如果能跑一个浏览器服务,可以统一管理浏览器实例
2. 截图/PDF 生成:需要自动化生成网页快照的场景
3. 复杂页面抓取:SPA、需要登录的页面、动态内容渲染
不过 OpenClaw 内置的 browser 工具可能已经覆盖了大部分场景。Browserless 更适用于高并发、生产化、多实例的场景。
七、评分
| 维度 | 评分 | 说明 |
|---|---|---|
| 代码质量 | ⭐⭐⭐⭐ | 架构清晰,TS 类型完整,手写 HTTP 服务器有胆识 |
| 文档完善度 | ⭐⭐⭐⭐⭐ | README, 官网, 文档站都非常好 |
| 易用性 | ⭐⭐⭐⭐⭐ | `docker run` 一行启动 |
| 许可友好度 | ⭐⭐ | SSPL 对商业不友好 |
| 社区活跃度 | ⭐⭐⭐⭐ | 44 open issues, 讨论活跃 |
| 可扩展性 | ⭐⭐⭐ | 进程内队列限制水平扩展 |
| 测试覆盖 | ⭐⭐⭐ | 核心模块覆盖了但不够全 |
综合评分: 4.0/5
八、总结
Browserless 是当前最成熟的开源 Headless Browser as a Service 方案。它的核心价值不是技术突破,而是把 Puppeteer/Playwright 的生产部署痛点——浏览器实例管理、并发控制、资源隔离、健康检查——打包成一个干净的 Docker 镜像。
对于个人开发者或小团队,docker run -p 3000:3000 ghcr.io/browserless/chromium 然后改一行连接代码就能用,体验极好。
对于需要大规模浏览器自动化的场景,建议先自托管 Browserless,不够用了再考虑 Browserbase 或自建方案。
> 一句话:如果你在生产环境用过 Puppeteer,你就会知道维护浏览器实例有多痛苦。Browserless 就是那个帮你把脏活干完的工具。