lightpanda-browser
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseLightpanda — Headless Browser for AI & Automation
Lightpanda — 面向AI与自动化的无头浏览器
Skill by ara.so — Daily 2026 Skills collection
Lightpanda is a headless browser built from scratch in Zig, designed for AI agents, web scraping, and automation. It uses 9x less memory and runs 11x faster than Chrome headless.
Key facts:
- Not based on Chromium, Blink, or WebKit — clean-slate Zig implementation
- JavaScript execution via V8 engine
- CDP (Chrome DevTools Protocol) compatible — works with Playwright, Puppeteer, chromedp
- Respects via
robots.txtflag--obey_robots - Beta status, actively developed
- License: AGPL-3.0
来自ara.so的技能指南 — 2026每日技能合集
Lightpanda是一款完全基于Zig从零构建的无头浏览器,专为AI Agent、网页抓取和自动化场景设计。它的内存占用比Chrome无头模式少9倍,运行速度快11倍。
核心特性:
- 不基于Chromium、Blink或WebKit——完全基于Zig从零实现
- 通过V8引擎执行JavaScript
- 兼容CDP(Chrome DevTools Protocol)——可与Playwright、Puppeteer、chromedp配合使用
- 通过参数遵循
--obey_robots规则robots.txt - 处于Beta阶段,正在积极开发中
- 许可证:AGPL-3.0
Installation
安装
macOS (Apple Silicon)
macOS(Apple Silicon)
bash
curl -L -o lightpanda https://github.com/lightpanda-io/browser/releases/download/nightly/lightpanda-aarch64-macos
chmod a+x ./lightpandabash
curl -L -o lightpanda https://github.com/lightpanda-io/browser/releases/download/nightly/lightpanda-aarch64-macos
chmod a+x ./lightpandaLinux (x86_64)
Linux(x86_64)
bash
curl -L -o lightpanda https://github.com/lightpanda-io/browser/releases/download/nightly/lightpanda-x86_64-linux
chmod a+x ./lightpandabash
curl -L -o lightpanda https://github.com/lightpanda-io/browser/releases/download/nightly/lightpanda-x86_64-linux
chmod a+x ./lightpandaDocker
Docker
bash
undefinedbash
undefinedSupports amd64 and arm64
支持amd64和arm64
docker run -d --name lightpanda -p 9222:9222 lightpanda/browser:nightly
undefineddocker run -d --name lightpanda -p 9222:9222 lightpanda/browser:nightly
undefinedCLI Usage
CLI使用方法
Fetch a URL (dump rendered HTML)
获取URL(导出渲染后的HTML)
bash
./lightpanda fetch --obey_robots --log_format pretty --log_level info https://example.combash
./lightpanda fetch --obey_robots --log_format pretty --log_level info https://example.comStart CDP Server
启动CDP服务器
bash
./lightpanda serve --obey_robots --log_format pretty --log_level info --host 127.0.0.1 --port 9222This launches a WebSocket-based CDP server for programmatic control.
bash
./lightpanda serve --obey_robots --log_format pretty --log_level info --host 127.0.0.1 --port 9222这会启动一个基于WebSocket的CDP服务器,用于程序化控制。
CLI Flags
CLI参数
| Flag | Description |
|---|---|
| Respect robots.txt rules |
| Human-readable log output |
| Log verbosity: |
| Bind address for CDP server |
| Port for CDP server |
| Disable TLS verification (testing only) |
| 参数 | 描述 |
|---|---|
| 遵循robots.txt规则 |
| 生成人类可读的日志输出 |
| 日志详细程度: |
| CDP服务器的绑定地址 |
| CDP服务器的端口 |
| 禁用TLS验证(仅用于测试) |
Playwright Integration
Playwright集成
Start the CDP server, then connect Playwright to it:
javascript
import { chromium } from 'playwright-core';
const browser = await chromium.connectOverCDP('http://127.0.0.1:9222');
const context = await browser.contexts()[0] || await browser.newContext();
const page = await context.newPage();
await page.goto('https://example.com', { waitUntil: 'networkidle' });
const title = await page.title();
const content = await page.content();
console.log(`Title: ${title}`);
console.log(`HTML length: ${content.length}`);
await browser.close();启动CDP服务器后,将Playwright连接到它:
javascript
import { chromium } from 'playwright-core';
const browser = await chromium.connectOverCDP('http://127.0.0.1:9222');
const context = await browser.contexts()[0] || await browser.newContext();
const page = await context.newPage();
await page.goto('https://example.com', { waitUntil: 'networkidle' });
const title = await page.title();
const content = await page.content();
console.log(`Title: ${title}`);
console.log(`HTML length: ${content.length}`);
await browser.close();Puppeteer Integration
Puppeteer集成
javascript
import puppeteer from 'puppeteer-core';
const browser = await puppeteer.connect({
browserWSEndpoint: 'ws://127.0.0.1:9222',
});
const context = await browser.createBrowserContext();
const page = await context.newPage();
await page.goto('https://example.com', { waitUntil: 'networkidle0' });
const title = await page.title();
const text = await page.evaluate(() => document.body.innerText);
console.log(`Title: ${title}`);
console.log(`Body text: ${text.substring(0, 200)}`);
await page.close();
await browser.close();javascript
import puppeteer from 'puppeteer-core';
const browser = await puppeteer.connect({
browserWSEndpoint: 'ws://127.0.0.1:9222',
});
const context = await browser.createBrowserContext();
const page = await context.newPage();
await page.goto('https://example.com', { waitUntil: 'networkidle0' });
const title = await page.title();
const text = await page.evaluate(() => document.body.innerText);
console.log(`Title: ${title}`);
console.log(`Body text: ${text.substring(0, 200)}`);
await page.close();
await browser.close();Go (chromedp) Integration
Go(chromedp)集成
go
package main
import (
"context"
"fmt"
"log"
"github.com/chromedp/chromedp"
)
func main() {
allocCtx, cancel := chromedp.NewRemoteAllocator(context.Background(), "ws://127.0.0.1:9222")
defer cancel()
ctx, cancel := chromedp.NewContext(allocCtx)
defer cancel()
var title string
err := chromedp.Run(ctx,
chromedp.Navigate("https://example.com"),
chromedp.Title(&title),
)
if err != nil {
log.Fatal(err)
}
fmt.Println("Title:", title)
}go
package main
import (
"context"
"fmt"
"log"
"github.com/chromedp/chromedp"
)
func main() {
allocCtx, cancel := chromedp.NewRemoteAllocator(context.Background(), "ws://127.0.0.1:9222")
defer cancel()
ctx, cancel := chromedp.NewContext(allocCtx)
defer cancel()
var title string
err := chromedp.Run(ctx,
chromedp.Navigate("https://example.com"),
chromedp.Title(&title),
)
if err != nil {
log.Fatal(err)
}
fmt.Println("Title:", title)
}Python Integration
Python集成
python
import asyncio
from playwright.async_api import async_playwright
async def main():
async with async_playwright() as p:
browser = await p.chromium.connect_over_cdp("http://127.0.0.1:9222")
context = browser.contexts[0] if browser.contexts else await browser.new_context()
page = await context.new_page()
await page.goto("https://example.com", wait_until="networkidle")
title = await page.title()
content = await page.content()
print(f"Title: {title}")
print(f"HTML length: {len(content)}")
await browser.close()
asyncio.run(main())python
import asyncio
from playwright.async_api import async_playwright
async def main():
async with async_playwright() as p:
browser = await p.chromium.connect_over_cdp("http://127.0.0.1:9222")
context = browser.contexts[0] if browser.contexts else await browser.new_context()
page = await context.new_page()
await page.goto("https://example.com", wait_until="networkidle")
title = await page.title()
content = await page.content()
print(f"Title: {title}")
print(f"HTML length: {len(content)}")
await browser.close()
asyncio.run(main())Web Scraping Patterns
网页抓取模式
Batch Page Fetching
批量页面获取
javascript
import { chromium } from 'playwright-core';
const browser = await chromium.connectOverCDP('http://127.0.0.1:9222');
const context = await browser.newContext();
const urls = [
'https://example.com/page1',
'https://example.com/page2',
'https://example.com/page3',
];
for (const url of urls) {
const page = await context.newPage();
await page.goto(url, { waitUntil: 'networkidle' });
const data = await page.evaluate(() => ({
title: document.title,
text: document.body.innerText,
links: [...document.querySelectorAll('a[href]')].map(a => a.href),
}));
console.log(JSON.stringify(data, null, 2));
await page.close();
}
await browser.close();javascript
import { chromium } from 'playwright-core';
const browser = await chromium.connectOverCDP('http://127.0.0.1:9222');
const context = await browser.newContext();
const urls = [
'https://example.com/page1',
'https://example.com/page2',
'https://example.com/page3',
];
for (const url of urls) {
const page = await context.newPage();
await page.goto(url, { waitUntil: 'networkidle' });
const data = await page.evaluate(() => ({
title: document.title,
text: document.body.innerText,
links: [...document.querySelectorAll('a[href]')].map(a => a.href),
}));
console.log(JSON.stringify(data, null, 2));
await page.close();
}
await browser.close();Extract Structured Data
提取结构化数据
javascript
const data = await page.evaluate(() => {
const items = document.querySelectorAll('.product-card');
return [...items].map(item => ({
name: item.querySelector('h2')?.textContent?.trim(),
price: item.querySelector('.price')?.textContent?.trim(),
link: item.querySelector('a')?.href,
}));
});javascript
const data = await page.evaluate(() => {
const items = document.querySelectorAll('.product-card');
return [...items].map(item => ({
name: item.querySelector('h2')?.textContent?.trim(),
price: item.querySelector('.price')?.textContent?.trim(),
link: item.querySelector('a')?.href,
}));
});Docker Compose (with your app)
Docker Compose(与你的应用配合)
yaml
services:
lightpanda:
image: lightpanda/browser:nightly
ports:
- "9222:9222"
restart: unless-stopped
scraper:
build: .
depends_on:
- lightpanda
environment:
- BROWSER_WS_ENDPOINT=ws://lightpanda:9222yaml
services:
lightpanda:
image: lightpanda/browser:nightly
ports:
- "9222:9222"
restart: unless-stopped
scraper:
build: .
depends_on:
- lightpanda
environment:
- BROWSER_WS_ENDPOINT=ws://lightpanda:9222Supported Web APIs
支持的Web API
Lightpanda supports (partial, expanding):
- DOM tree manipulation and querying
- JavaScript execution (V8)
- XMLHttpRequest (XHR)
- Fetch API
- Cookie management
- Network interception
- Proxy support
Lightpanda支持(部分支持,正在扩展):
- DOM树操作与查询
- JavaScript执行(V8)
- XMLHttpRequest(XHR)
- Fetch API
- Cookie管理
- 网络拦截
- 代理支持
Configuration
配置
| Environment Variable | Description |
|---|---|
| Set to |
| 环境变量 | 描述 |
|---|---|
| 设置为 |
Performance Comparison
性能对比
| Metric | Lightpanda | Chrome Headless |
|---|---|---|
| Memory | ~9x less | Baseline |
| Speed | ~11x faster | Baseline |
| Binary size | Small (Zig) | Large (Chromium) |
| Rendering | No visual rendering | Full rendering engine |
| 指标 | Lightpanda | Chrome无头模式 |
|---|---|---|
| 内存占用 | 约少9倍 | 基准值 |
| 速度 | 约快11倍 | 基准值 |
| 二进制文件大小 | 小巧(基于Zig) | 庞大(基于Chromium) |
| 渲染能力 | 无视觉渲染 | 完整渲染引擎 |
When to Use Lightpanda
何时使用Lightpanda
Use Lightpanda when:
- Running AI agents that need to browse the web
- Batch scraping at scale (memory/CPU savings matter)
- Automating form submissions and data extraction
- Running in containers where resources are limited
- You need CDP compatibility but not full visual rendering
Use Chrome/Playwright instead when:
- You need pixel-perfect screenshots or PDF generation
- You need full Web API coverage (Lightpanda is still partial)
- Visual regression testing
- Testing browser-specific rendering behavior
适合使用Lightpanda的场景:
- 运行需要浏览网页的AI Agent
- 大规模批量抓取网页(内存/CPU节省至关重要)
- 自动化表单提交与数据提取
- 在资源有限的容器环境中运行
- 需要CDP兼容性但无需完整视觉渲染
适合使用Chrome/Playwright的场景:
- 需要像素级精确的截图或PDF生成
- 需要完整的Web API支持(Lightpanda目前仅支持部分)
- 视觉回归测试
- 测试浏览器特定的渲染行为
Building from Source
从源码构建
Requires: Zig 0.15.2, Rust, CMake, system dependencies.
bash
undefined依赖:Zig 0.15.2、Rust、CMake、系统依赖。
bash
undefinedUbuntu/Debian dependencies
Ubuntu/Debian依赖
sudo apt install xz-utils ca-certificates pkg-config libglib2.0-dev clang make curl
sudo apt install xz-utils ca-certificates pkg-config libglib2.0-dev clang make curl
Build
构建
git clone https://github.com/lightpanda-io/browser.git
cd browser
zig build
git clone https://github.com/lightpanda-io/browser.git
cd browser
zig build
Optional: pre-build V8 snapshot for faster startup
可选:预构建V8快照以加快启动速度
zig build snapshot_creator -- src/snapshot.bin
zig build -Dsnapshot_path=../../snapshot.bin
undefinedzig build snapshot_creator -- src/snapshot.bin
zig build -Dsnapshot_path=../../snapshot.bin
undefinedTroubleshooting
故障排除
Connection refused on port 9222:
- Ensure is running
./lightpanda serve - Check if connecting from Docker/remote
--host 0.0.0.0
Playwright script breaks after update:
- Lightpanda is beta — Playwright's capability detection may behave differently across versions
- Pin your Lightpanda version or use nightly consistently
Missing Web API support:
- Check the zig-js-runtime repo for current API coverage
- File issues at lightpanda-io/browser
端口9222连接被拒绝:
- 确保正在运行
./lightpanda serve - 如果从Docker/远程连接,检查是否设置了
--host 0.0.0.0
Playwright脚本在更新后失效:
- Lightpanda处于Beta阶段——不同版本间Playwright的能力检测可能表现不同
- 固定Lightpanda版本或始终使用nightly版本
缺少Web API支持:
- 查看zig-js-runtime仓库了解当前API覆盖情况
- 在lightpanda-io/browser提交问题