今天在 GitHub Trending 上看到一个有意思的项目:Obscura,一个完全由 Rust 编写的开源无头浏览器引擎,主打轻量、高速和内置反检测,目标是不依赖 Chromium,成为 Puppeteer 和 Playwright 的直接替代品。

一、项目概述

Obscura 是一个专为 AI 代理自动化和大规模网页爬取设计的无头浏览器引擎,完全使用 Rust 编写,不依赖 Chromium 或 Node.js,安装包仅约 70MB,运行时内存仅 30MB(对比 Chrome Headless 的 200+ MB)。它实现了 Chrome DevTools Protocol(CDP),可以直接作为 Puppeteer 和 Playwright 的后端使用,对已有项目实现零成本迁移。

核心特性:

  • 零依赖 Chromium:内置 V8 JavaScript 引擎,完整执行 JS 渲染
  • CDP 协议兼容:支持 Puppeteer-core 和 Playwright-core 直连
  • 内置反检测:会话级指纹随机化(GPU、屏幕、Canvas、Audio),navigator.webdriver = undefined,事件 isTrusted 等
  • 内置追踪器屏蔽:预置 3,520 个追踪域名,广告/分析/遥测脚本自动拦截
  • 渲染引擎:纯 Rust 实现 CSS 布局、页面截图和 PDF 导出(taffy + tiny-skia)
  • 多平台支持:Linux(x86_64 / ARM64)、macOS(Apple Silicon / Intel)、Windows,以及 Docker 镜像

二、技术原理

2.1 架构设计

Obscura 采用 Workspace 多 crates 分层架构,从核心到顶层依次为:

Crate职责
obscura-domHTML 解析(html5ever)+ CSS 选择器
obscura-netHTTP/SOCKS 代理、Cookie 管理
obscura-jsV8 JS 引擎集成
obscura-render纯 Rust 渲染管线(taffy 布局 + tiny-skia 绘图)
obscura-cdpCDP 协议实现
obscura-mcpModel Context Protocol 服务端(AI 代理集成)
obscura-cliCLI 入口(fetch / serve / scrape / mcp 命令)

Cargo.toml 可以看到项目依赖的关键 crate:

html5ever = "0.39"
selectors = "0.26"
taffy = "0.12"          # CSS 布局引擎(本地 vendor 分支)
tiny-skia = "0.12"      # 纯 Rust 2D 光栅化
tokio = { version = "1", features = ["full"] }
reqwest = { version = "0.12", features = ["gzip", "brotli", "deflate", "rustls-tls", "socks"] }

反检测(Stealth)模式下,调用 BoringSSL 加密传输链,编译需要 CMake、Clang 和 libclang:

# 带 stealth 的完整构建
cargo build --release -p obscura-cli --bins --features render,stealth

2.2 性能基准

官方基准测试数据对比 Chrome:

页面类型ObscuraChrome Headless
静态 HTML51 ms~500 ms
JS + XHR + fetch84 ms~800 ms
动态脚本78 ms~700 ms

2.3 MCP 服务端

Obscura 还提供了 MCP(Model Context Protocol)服务端,允许 AI 代理(如 Claude Desktop、Cursor)直接调用浏览器自动化工具:

obscura mcp  # stdio 模式(默认)
obscura mcp --http --port 8080  # HTTP 模式

注册到 Claude Desktop 只需在配置文件加入:

{
  "mcpServers": {
    "obscura": {
      "command": "obscura",
      "args": ["mcp"]
    }
  }
}

三、安装与快速开始

3.1 二进制安装(推荐)

一行命令即可下载对应平台的最新发布版:

# Linux x86_64
curl -LO https://github.com/h4ckf0r0day/obscura/releases/latest/download/obscura-x86_64-linux.tar.gz
tar xzf obscura-x86_64-linux.tar.gz
./obscura fetch https://example.com --eval "document.title"

# macOS Apple Silicon
curl -LO https://github.com/h4ckf0r0day/obscura/releases/latest/download/obscura-aarch64-macos.tar.gz
tar xzf obscura-aarch64-macos.tar.gz

# Arch Linux
yay -S obscura-browser

无任何外部依赖,下载后可直接运行。

3.2 Docker 部署

docker run -d --name obscura -p 127.0.0.1:9222:9222 h4ckf0r0day/obscura

基于 distroless/cc 构建,镜像仅约 57MB,无 shell,无包管理器。

3.3 从源码构建

git clone https://github.com/h4ckf0r0day/obscura.git
cd obscura
cargo build --release -p obscura-cli --bins --features render

首次构建 V8 引擎约需 5 分钟(编译结果会被缓存)。

四、使用方法与实战

4.1 单页抓取

# 获取页面标题
obscura fetch https://example.com --eval "document.title"

# 提取所有链接(NDJSON)
obscura fetch https://news.ycombinator.com --dump links

# 截图
obscura fetch https://example.com -s page.png

# 通过 SOCKS 代理抓取
obscura --proxy socks5://127.0.0.1:1080 fetch https://example.com --dump text

4.2 并行批量爬取

obscura scrape url1 url2 url3 ... \
  --concurrency 25 \
  --eval "document.querySelector('h1').textContent" \
  --format json

4.3 作为 Puppeteer 后端

只需将 ws://127.0.0.1:9222/devtools/browser 作为 WebSocket 端点传入 puppeteer-core:

import puppeteer from 'puppeteer-core';

const browser = await puppeteer.connect({
  browserWSEndpoint: 'ws://127.0.0.1:9222/devtools/browser',
});

const page = await browser.newPage();
await page.goto('https://news.ycombinator.com');

const stories = await page.evaluate(() =>
  Array.from(document.querySelectorAll('.titleline > a'))
    .map(a => ({ title: a.textContent, url: a.href }))
);
console.log(stories);

await browser.disconnect();

4.4 截图与 PDF 导出(内置渲染引擎)

await page.setViewport({ width: 1440, height: 1000 });
await page.goto('https://example.com', { waitUntil: 'load' });
await page.screenshot({ path: 'page.png', fullPage: true });
await page.pdf({ path: 'page.pdf', format: 'A4', printBackground: true });

4.5 Stealth 模式:反检测爬虫

# 启动带反检测的 CDP 服务
obscura serve --port 9222 --stealth

# 单次请求启用反检测
obscura fetch https://example.com --stealth --screenshot stealth.png

Stealth 模式自动完成:Canvas/WebGL 指纹随机化、navigator.userAgentData 伪造真实值、事件 isTrusted = true、内置属性隐藏(Object.keys 安全)等。

五、常见问题与解决方案

Q: 首次构建报错 JavaScript heap out of memory A: heavy SPA 页面 JS 执行量大,默认 30s 脚本预算可能不足。通过 --v8-flags 增大堆内存:obscura --v8-flags "--max-old-space-size=4096" fetch <url>

Q: Stealth 模式编译失败,提示缺少 BoringSSL? A: 需要额外安装编译工具链:sudo apt-get install build-essential cmake clang libclang-dev llvm-dev

Q: 大文件下载时内存溢出? A: Obscura 默认缓存上限为 2 MiB。对于大文件,通过 CDP Fetch.takeResponseBodyAsStream + IO.read 分块读取,而非一次性 Network.getResponseBody。

Q: Docker 镜像无法在 Apple Silicon 上运行? A: 目前 Docker Hub 镜像为 Linux x86_64 构建,Apple Silicon Mac 建议直接下载 macOS ARM64 二进制tar.gz 包,无需 Rosetta 转译。

Q: 想在 Claude Desktop 中使用,但不知道如何配置 MCP? A: 安装 Obscura 二进制后,按上方 2.3 节的 JSON 配置写入 Claude Desktop 配置,重启后 Obscura MCP 工具即可在对话中调用。

六、总结

Obscura 用纯 Rust 重新实现了无头浏览器的核心能力,在内存占用(30MB vs 200MB)、启动速度(毫秒级 vs ~2s)和反检测方面全面领先 Chrome Headless。作为 Puppeteer/Playwright 的 CDP 替代后端,现有的 Node.js 爬虫代码几乎无需改动即可迁移。对于需要大规模浏览器自动化的 AI 代理或爬虫场景,Obscura 是一个值得优先考虑的轻量级引擎。