mcpField
L
lightpanda

lightpanda

github.com/lightpanda-ioAgent 工作流1051.4k 次安装3 周前更新
代码仓库

关于 lightpanda

面向 AI Agent 的无头浏览器技能,用于无需图形渲染的数据提取和网页自动化。它提供 MCP 服务、CLI、CDP 服务及可重复执行的 PandaScript。

主要功能

  1. 01执行 JavaScript 并提取网页内容
  2. 02通过 MCP 工具浏览与操作页面
  3. 03CLI 单次抓取页面
  4. 04提供 CDP 服务供 Playwright 或 Puppeteer 使用
  5. 05用 PandaScript 重放保存的任务

适用场景

  1. 01浏览网页并提取结构化数据
  2. 02填写表单或操作页面元素
  3. 03通过命令行快速抓取页面内容
  4. 04重复执行已保存的浏览任务

MCP 相关

Lightpanda 提供基于 stdio 的 MCP 服务,向 Agent 暴露网页导航、搜索、读取、提取和交互工具,以及页面 HTML 与 Markdown 资源。HTTP 传输还支持独立浏览会话。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/lightpanda-io/agent-skill --skill lightpanda

安装后在 Claude Code 中输入/lightpanda确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

.gitignore
README.md
LICENSE
.claude-plugin/
marketplace.json
scripts/
install.sh

详细介绍

Lightpanda

当你不需要图形渲染时,可用它替代 Chrome/Chromium 进行数据提取和网页自动化。

Lightpanda 是一款从零构建、面向 AI Agent 的无头浏览器。它的速度比 Chrome 快 9 倍,内存占用少 16 倍。它支持执行 JavaScript,提供内置 MCP 服务和针对 Agent 优化的工具、用于快速抓取的 CLI,以及用于 Playwright/Puppeteer 的 CDP 服务。

内置网页搜索的替代方案

当内置 Web Search 工具不可用,或你需要更好地控制搜索结果(例如,跟踪链接以提取完整页面内容)时,可以使用 Lightpanda 自带的 search MCP 工具作为替代方案(默认由 Keenable 的公共端点提供支持;也可以在设置相应搜索引擎的 API 密钥后使用 Brave、Tavily、Exa 或 Keenable)。 如果内置 Web Search 工具可用且能满足需求,请优先使用它。

安装

运行下面的安装程序前,请先检查是否已安装 Lightpanda(command -v lightpanda)。

  • Claude Code:
    bash ${CLAUDE_SKILL_DIR}/scripts/install.sh
    
    ${CLAUDE_SKILL_DIR} 是 Claude Code 的替换变量,无论 shell 当前工作目录是什么,它都会解析为此技能自身所在的目录——这是必需的,因为此技能作为插件运行时,shell 的 cwd 是你的项目目录,而不是技能的安装位置。
  • 其他任何 Agent 运行时(Cursor、Codex CLI、Gemini CLI 等):不支持此替换变量。scripts/install.sh 与此文件位于同一目录——请在那里找到它,并使用对应路径运行,例如 bash /path/to/this/skill/scripts/install.sh。

Lightpanda 仅适用于 Linux 和 macOS。Windows 可通过 WSL2 使用。

更倾向于使用包管理器?请参阅通过包管理器安装:

  • Homebrew(macOS/Linux):brew install lightpanda-io/browser/lightpanda
  • AUR(Arch Linux):yay -S lightpanda-bin(或使用 lightpanda-nightly-bin 跟踪 nightly 版本)
  • Debian/Ubuntu(0.3.0+):从每个标记版本获取 .deb 包

与始终跟踪最新 nightly 版本的 scripts/install.sh 不同,除非你明确选择 nightly 变体,否则这些方式会固定到稳定版本。

此二进制文件是一个快速迭代的 nightly 构建。如果遇到崩溃或问题,请再次运行上面的安装命令,以更新到最新版本(每天最多一次)。

如果更新后问题仍然存在,请在 https://github.com/lightpanda-io/browser/issues 提交 GitHub issue,并附上:

  • 崩溃跟踪信息/错误输出,或对异常行为的描述
  • 能复现问题的脚本或 MCP 工具调用
  • 目标 URL,以及预期结果与实际结果

如何选择

Lightpanda 提供多种接口。请根据需求选择:

接口最适合工作方式
MCP 服务Agent 工作流、交互式浏览、填写表单通过 stdio 提供结构化工具——专为大模型 Agent 打造
CLI 抓取快速提取单个页面单条命令,无需服务
CDP 服务使用 Playwright/Puppeteer 进行自定义自动化WebSocket 协议,可全面控制浏览器
Agent 模式一次性自然语言任务,或编写 PandaScript 以供以后使用lightpanda agent——由大模型驱动的 CLI/REPL,可选择使用 --task "..." --save script.js
已保存脚本(PandaScript)确定性地重复执行相同任务,避免消耗 token纯 JS 脚本,通过 lightpanda run 重放——无需调用大模型

MCP 服务(推荐用于 Agent)

MCP 服务是 Agent 使用 Lightpanda 最简单的方式。它通过 stdio 提供专用工具,除二进制文件外无需额外设置。

Claude Code 设置
claude mcp add lightpanda -- lightpanda mcp

若要遵守 robots.txt,请在命令后追加 --obey-robots。

其他 MCP 客户端设置

添加到你的 MCP 客户端配置中:

{
  "mcpServers": {
    "lightpanda": {
      "command": "lightpanda",
      "args": ["mcp"]
    }
  }
}
可用的 MCP 工具

对于同时接受 selector 和 backendNodeId 的工具,两者都可用于定位目标元素——为便于重现(例如在已保存的脚本中),优先使用 selector;backendNodeId 来自先前的 tree 或 findElement 调用。接受可选 url 的读取工具会先导航到该 URL,无需另行调用 goto。

导航与搜索:

  • goto — 导航到某个 URL 并加载页面
  • search — 执行网页搜索并以 markdown 格式返回结果:包含 {title, url, snippet} 的编号列表。依次尝试 Brave、Tavily、Exa,然后是 Keenable;仅当设置了相应 API 密钥(BRAVE_API_KEY、TAVILY_API_KEY、EXA_API_KEY 或 KEENABLE_API_KEY)时才会尝试;Keenable 也可通过其公共端点在不使用密钥的情况下运行(按客户端 IP 限流)

读取页面(都接受可选的 url,用于先导航):

  • markdown — 以 markdown 格式获取页面内容或其子树
  • html — 获取文档的原始 HTML;若限定到单个节点,则获取该节点的 outerHTML
  • screenshot — 将页面或某个节点渲染为 PNG(呈现的是 Lightpanda 计算出的文本布局,并非像素级精准渲染)
  • tree — 简化的语义 DOM 树,针对 AI 推理进行优化:每个节点包含 role、name、value 和 backendNodeId(支持按 backendNodeId 过滤及限制 maxDepth)
  • links — 提取所有链接,包括文本、解析后的 href 和 backendNodeId
  • nodeDetails — 根据 backendNodeId 获取节点的标签、role、name、属性和状态,以及可直接使用的 CSS 选择器
  • findElement — 根据 role 和/或可访问名称查找交互式元素
  • interactiveElements — 列出页面上的所有交互式元素
  • structuredData — 提取结构化数据(JSON-LD、OpenGraph 等)
  • detectForms — 检测表单及其字段结构和类型

数据提取与脚本编写:

  • extract — 使用将输出字段名称映射到 CSS 选择器规范的架构来提取结构化数据
  • evaluate — 在页面上下文中执行 JavaScript;末尾的裸表达式会返回其值,并支持顶层 await/return

与页面交互(每次操作后都会返回页面 URL 和标题):

  • click — 点击交互式元素
  • fill — 在输入框、文本区域或选择框中填入文本
  • scroll — 滚动页面或特定元素
  • hover — 将鼠标悬停在元素上,触发 mouseover/mouseenter
  • press — 按下键盘按键,并派发 keydown/keyup
  • selectOption — 按值在 <select> 中选择一个选项
  • setChecked — 勾选或取消勾选复选框或单选按钮

等待:

  • waitForSelector — 等待 CSS 选择器匹配(默认超时:5000ms)
  • waitForScript — 等待某个 JS 表达式返回真值,并在每个时间间隔重新检查
  • waitForState — 等待加载状态(load、domcontentloaded、networkalmostidle、networkidle、done),且不会发生导航

状态与调试:

  • getUrl — 获取浏览器当前加载的 URL
  • getCookies — 获取当前页面主机、其他 url 或 all 的 Cookie
  • getEnv — 读取一个 LP_* 环境变量,或列出已设置的 LP_* 名称
  • consoleLogs — 获取缓冲的 console.log/warn/error 消息,然后清空缓冲区

会话(与下文所述的 HTTP 传输方式相关):

  • save — 将会话保存为可复用的 PandaScript(参见“已保存脚本”部分)
  • session_new — 创建一个新的独立浏览器会话(拥有自己的页面、Cookie 和内存),并返回其 ID
  • session_list — 列出活动会话及其 ID 和当前 URL
  • session_close — 关闭一个会话(无法关闭 default 会话)
可用的 MCP 资源
  • mcp://page/html — 当前页面完整序列化后的 HTML
  • mcp://page/markdown — 当前页面的 Token 高效 markdown 表示(内容与 markdown 工具相同)
多个会话(HTTP 传输)

传入 --port,即可通过 HTTP 而非 stdio 提供 MCP 服务,让每个客户端拥有独立的浏览会话:lightpanda mcp --port 8000。不带 Mcp-Session-Id 标头的 initialize 调用会创建一个新会话,并在响应标头中返回其 ID;后续调用请重复使用该 ID(也可以与另一个客户端共享)。不带会话标头的调用会回退到始终存在的 default 会话。使用 session_new / session_list / session_close 显式管理会话。通过 stdio(如上方的 Claude Code 配置)时,始终只有一个 default 会话。对于读取不可信内容的任务,请为其单独分配一个会话(参见 最佳实践)。

添加 --cdp-port <INT>,还可以在同一进程上运行 CDP(WebSocket)服务——如果工作流中有部分操作需要原始 CDP(例如 Playwright/Puppeteer),同时又需要 MCP,这会很有用。它不能与 --port 同时使用,因为两者共用同一个网络监听器。

MCP 使用示例

典型的 Agent 工作流:

  1. 使用 goto 打开一个 URL
  2. 使用 tree 或 markdown 了解页面
  3. 使用 interactiveElements 或 findElement 查找可点击或可填写的元素
  4. 使用 click / fill 进行交互
  5. 使用 extract 或 markdown 获取结果

CLI Fetch — 快速提取

无需启动服务,即可一次性提取页面内容:

lightpanda fetch --dump markdown --wait-until networkidle https://example.com
选项
  • --dump — 输出格式:html、markdown、png、pdf、semantic_tree、semantic_tree_text(MCP 中对应 semantic_tree* 的名称为 tree)
  • --wait-until — 等待策略:load、domcontentloaded、networkalmostidle、networkidle、done(默认值)
  • --wait-ms — 最长等待时间,单位为毫秒(默认值:5000)
  • --wait-selector — 等待 CSS 选择器出现,在 --wait-until 条件满足后检查
  • --wait-script — 等待 JS 表达式返回真值,在 --wait-until 条件满足后检查
  • --strip-mode — 从输出中移除标签组:js、css、ui、invisible、shell、clutter(以逗号分隔)
  • --with-frames — 在转储内容中包含 iframe 内容
  • --json — 将抓取状态打印为 JSON,而不是转储内容或与转储内容一同打印;抓取多个 URL 时必需
  • --inject-script / --inject-script-file — 在解析文档的 <head> 时、运行任何页面脚本之前执行的 JavaScript。可重复指定;按 CLI 中的顺序运行
  • --terminate-ms — 毫秒级硬截止时间;超时后强制终止 JS 执行(与 --wait-ms 不同,后者只会停止等待)

所有命令共用的标志见下方的 Common Options;fetch 命令指南提供了完整参考。

示例

将页面提取为 Markdown:

lightpanda fetch --dump markdown https://example.com

提取语义树(紧凑,适合 AI 阅读):

lightpanda fetch --dump semantic_tree_text --wait-until networkidle https://example.com

抓取时为加载较慢的页面延长等待时间:

lightpanda fetch --dump html --wait-ms 10000 --wait-until networkidle https://example.com

CDP 服务 — 高级自动化

通过 Playwright 或 Puppeteer 完全控制浏览器:

启动浏览器服务
lightpanda serve --host 127.0.0.1 --port 9222

选项:

  • --cdp-max-connections — 同时建立的 CDP 连接数上限(默认值:16)
  • --cdp-max-message-size — WebSocket 入站消息大小上限(默认值:1MB)
  • --disable-metrics — 禁用 /metrics Prometheus 端点
  • --advertise-host — 在例如 /json/version 响应中公布的主机;当 --host 为 0.0.0.0 时很有用

所有命令共用的标志见下方的 Common Options;serve 命令指南提供了完整参考。

与 playwright-core 配合使用

使用 playwright-core(而非完整的 playwright 包)进行连接:

const { chromium } = require('playwright-core');

(async () => {
  const browser = await chromium.connectOverCDP({
    endpointURL: 'ws://127.0.0.1:9222',
  });

  const context = await browser.newContext({});
  const page = await context.newPage();

  await page.goto('https://example.com');
  const title = await page.title();
  const content = await page.textContent('body');

  console.log(JSON.stringify({ title, content }));

  await page.close();
  await context.close();
  await browser.close();
})();
与 puppeteer-core 配合使用

使用 puppeteer-core(而非完整的 puppeteer 包)进行连接。此代码片段仅展示与上方 Playwright 示例的差异,因此无法独立运行。请复用该示例中的设置和清理代码,并替换为以下代码行。

const puppeteer = require('puppeteer-core');

const browser = await puppeteer.connect({
  browserWSEndpoint: 'ws://127.0.0.1:9222',
});
const context = await browser.createBrowserContext(); // not newContext()
const page = await context.newPage();
await page.goto('https://example.com', { waitUntil: 'networkidle0' }); // explicit waitUntil — puppeteer doesn't auto-wait like Playwright

其余内容(page.title()、page.close()、context.close()、browser.close())与 Playwright 示例相同。

自定义 LP CDP 域

Lightpanda 通过 CDP 提供自定义 LP 域,其中包含标准 Chrome DevTools Protocol 中没有的、针对 Agent 优化的方法。可通过 CDP 会话使用 page.evaluate 调用这些方法,也可以直接发送 WebSocket 消息。

内容提取:

  • LP.dump — 将页面或子树渲染为 html、markdown、png 或 pdf。参数:format(必需)、strip、selector、backendNodeId、maxBytes(仅限文本格式)
  • LP.getMarkdown — 已弃用,等同于将 format 设为 "markdown" 的 LP.dump。参数:nodeId(可选)
  • LP.getSemanticTree — 获取语义树表示。参数:format(文本格式使用 text)、prune(默认:true)、interactiveOnly、backendNodeId、maxDepth
  • LP.getStructuredData — 提取结构化数据(JSON-LD、OpenGraph 等)

交互元素:

  • LP.getInteractiveElements — 查找所有交互元素。参数:nodeId(可选)
  • LP.detectForms — 检测并提取表单信息
  • LP.getNodeDetails — 获取节点的详细信息。参数:backendNodeId(必需)
  • LP.waitForSelector — 等待 CSS 选择器匹配。参数:selector(必需)、timeout(默认:5000ms)

操作:

  • LP.clickNode — 点击节点。参数:nodeId 或 backendNodeId
  • LP.fillNode — 填写输入框或选择元素。参数:nodeId 或 backendNodeId、text
  • LP.scrollNode — 滚动页面或元素。参数:nodeId 或 backendNodeId(可选)、x、y

调试与配置:

  • LP.getContentSignal — 读取当前主机的建议性 Content-Signal robots.txt 偏好设置(contentsignals.org)。除非 --obey-robots 已填充存储,否则 available 为 false。
  • LP.handleJavaScriptDialog — 预先设置对下一个 window.alert/confirm/prompt 的响应(accept,以及可选的 promptText)。Lightpanda 会在无头模式下自动关闭对话框,因此必须在打开对话框的 JS 运行之前发送此命令,不能像标准 CDP 的 Page.handleJavaScriptDialog 那样在事后响应。
  • LP.configureCDP — 切换 CDP 兼容性行为。参数:disableSetCacheDisabled、obeyRobots、httpVersion(auto/1.1)(均可选)
  • LP.configureLoading — 按会话切换 iframe、worker、外部样式表和图像的加载。参数:subFrame、worker、externalStylesheets、images(均可选)
  • LP.version — 返回正在运行的 Lightpanda 版本

使用 Playwright CDP 会话的示例:

const client = await context.newCDPSession(page);

// Get page as markdown
const { markdown } = await client.send('LP.getMarkdown');

// Get semantic tree
const { semanticTree } = await client.send('LP.getSemanticTree', { format: 'text', maxDepth: 5 });

// Wait for element and click it
const { backendNodeId } = await client.send('LP.waitForSelector', { selector: '#submit-btn', timeout: 3000 });
await client.send('LP.clickNode', { backendNodeId });

已保存脚本(PandaScript)

PandaScript 是一种纯 JavaScript 自动化脚本,由 Lightpanda 直接运行——不调用大模型、结果确定且不消耗令牌。你只需完成一次任务、之后希望原样重复执行(例如按计划执行)时,就适合使用它。

有三种生成方式:

  • 会话中通过 MCP: 使用 path 和合成的 script 调用 save 工具——脚本编写规则请参阅该工具自身的说明。
  • 通过 CLI 单次生成: lightpanda agent --task "..." --save script.js 会根据自然语言任务合成脚本,而不是打印答案。
  • 交互式生成: lightpanda agent 会启动 REPL;使用自然语言或斜杠命令操作浏览器(每个 MCP 工具也可通过 /toolName key=value 调用,例如 /goto url=https://example.com),然后运行 /save script.js。

无需调用大模型即可重放:

lightpanda run script.js

有关脚本语义(原语、提取架构、常见错误),请参阅 pandascript 技能。它由运行时自身的工具架构生成,因此不会像手写说明那样产生偏差。PandaScript 指南 面向未加载技能、但在阅读此代码仓库的人,介绍相同内容。

常用选项

每条命令(fetch、serve、mcp、agent、run)均可使用这些选项,并非只有各节示例中展示的命令才能使用。lightpanda help <command> 会列出其余选项(代理、TLS、超时、存储)。

日志记录: --log-level(debug/info/warn/error/fatal)、--log-format(pretty/logfmt)。

身份标识:

  • --user-agent <string>:完全覆盖 User-Agent 标头;任何包含 "Mozilla" 的值都不允许使用,并且仍会发送 Sec-Ch-Ua: "Lightpanda";v="1"。--user-agent-suffix <string> 则会将内容追加到默认值 Lightpanda/X.Y 后(不能与 --user-agent 同时使用)。
  • --web-bot-auth-key-file <path> / --web-bot-auth-keyid <thumbprint> / --web-bot-auth-domain <domain>:使用 Ed25519 密钥为每个请求签名,以便网站通过你发布的密钥目录验证你的身份。

礼貌访问:

  • --obey-robots:获取并遵守 robots.txt(每个主机获取一次,并在会话期间缓存)。默认值为 false。
  • --http-nav-delay <ms>:对同一主机进行两次顶层导航之间的最短间隔。0(默认值)表示禁用此选项。--http-nav-burst <n> 用于指定应用延迟前可开始的导航次数(默认值为 1)。

效率:

  • --http-cache-dir <path>:用作网络资源文件系统缓存的目录(RFC 9111 重新验证)。省略此选项会禁用缓存。
  • --adblock-lists <file>:EasyList 语法的过滤文件;对被屏蔽主机名的请求会在发出前失败。可重复指定。
  • --block-urls "<pattern>":屏蔽与不区分大小写的 * 通配符模式匹配的 URL。可重复指定。

安全性: --block-private-networks:DNS 解析后,屏蔽发往私有/内部 IP 地址的 HTTP 请求。默认值为 false。

有关各选项的使用时机和原因,请参阅下文的最佳实践。

重要说明

  • 进行网络搜索时,请使用 search 工具,而非 Google。由于浏览器指纹识别,Google 会屏蔽 Lightpanda。
  • Lightpanda 正在快速开发中,偶尔可能会出现问题。它可以执行 JavaScript,因此适用于动态网站和 SPA。
  • 请谨慎看待 goto 的响应。 对于 DNS 和连接错误(例如 CouldntResolveHost),它会直接报告失败,因此这部分是可靠的。另外两种情况仍会显示为成功。发生超时时,它会返回“Navigation started but the page did not finish loading before the timeout.”,而不是报告失败。HTTP 错误页面(404、500)属于真实响应,因此 goto 会将导航到该页面报告为成功。如果响应状态很重要,请在后续读取内容时进行检查。
  • CDP 连接数限制: 默认情况下,每个进程最多支持 16 个并发 CDP 连接(可通过 --cdp-max-connections 调整)。每个连接支持 1 个上下文和 1 个页面。如需更高并行度,请在不同端口启动多个进程——Lightpanda 启动非常快,因此这种方式耗时很短。
  • CDP 状态管理: CDP 连接关闭时,浏览器会重置所有状态。请在整个会话期间保持 WebSocket 连接打开。每个连接都应始终创建新的上下文和页面,并在完成后关闭两者。
  • MCP 服务会自动处理连接管理——使用 MCP 工具时不受这些 CDP 限制影响。

最佳实践

Lightpanda 只会执行你请求的操作。它是浏览器,不是爬虫,也没有内置的礼貌策略;如何设置合适的行为由你负责。此处提到的标志已在上文的“常用选项”中说明;本节介绍何时需要关注各个选项。

标识你的流量。 运营方会对他们能够识别的流量进行路由、限速和加入允许列表。建议用户确认一个身份信息:名称(组织、项目或个人账号)以及一个运营方可以查看机器人行为并联系到你的 URL(例如代码仓库、文档页面或个人主页)。通过 --user-agent 传入;不要使用下面的占位符。

lightpanda serve --user-agent "<name>/1.0 (+https://<your-url>)"

用户代理字符串只是一个声明,任何人都可以发送。Web Bot Auth(--web-bot-auth-* 标志)可使其可验证;Cloudflare、Akamai、Google 和 AWS 都会检查签名。

要在同一主机上抓取很多页面? 启用 --obey-robots,并设置 --http-nav-delay 1000;只有确定主机能够承受时才降低该值。收到带有 Retry-After 的 429 或 503,意味着这个速度仍然太快:请在自己的代码中遵循该标头,因为 --http-nav-delay 不会处理它。

减少请求。最大的收益来自设计:

  • 优先选择批量来源:使用 git clone,而不是遍历网页 Git 托管平台;使用有文档说明的 API,而不是其 UI;使用 sitemap.xml,而不是发现链接。
  • 限制跟随链接的深度,以及每个域名保留的 URL 数量。避开无限 URL 空间(例如日历、任意差异对比和分面搜索);在其中漫游的任务永远不会结束,而且过程中看起来像是在发起攻击。
  • 对任何会运行多次的任务设置 --http-cache-dir;之后,未更改的资源只需重新验证。
  • 使用 --adblock-lists / --block-urls 拦截跟踪器和广告。默认不会获取子资源和外部样式表(例外情况是使用大模型的 Agent 模式:为进行可见性检查,它会加载样式表)。
  • 使用 search 工具,而不是浏览搜索结果页面。

为每项任务使用独立的浏览器。 全新实例不会保留任何 Cookie 或状态,并且限定作用范围可以限制不可信页面内容中的提示词注入造成的影响。每当你跟随页面提供的链接,而不是自己选择的链接时,都添加 --block-private-networks。CDP:每项任务使用一个新浏览器或上下文。MCP:stdio 模式在整个会话中只使用一个浏览器,因此需要每项任务使用一个浏览器时,请使用 HTTP 模式(--port)。

流程确定后,就不要再反复推导。 将其保存为 PandaScript(参见上文的“已保存脚本”部分),然后使用 lightpanda run 重放:无需花费令牌,失败也会以脚本错误的形式显现,而不是给出看似合理的错误答案。

脚本

  • scripts/install.sh — 安装 Lightpanda 二进制文件

评论

支持 Markdown