← 文章 / 未分类
lightpanda 6小时前 · 2026-09-09 00:39:39 · 2 阅读

使用 Lightpanda 的最佳实践

Céline Debled
Best Practices for Using Lightpanda

Lightpanda 只执行你发出的请求,如何正确使用取决于你。如果用模型驱动,就安装 agent skill;无论做什么,都用 --user-agent 标识你的流量。剩下的交给工作流来决定:批量抓页时加上 --obey-robots--http-nav-delay,模型消耗 token 时做好范围限定,跟随非自选链接时每个任务开一个全新浏览器。

先建立正确的认知:Lightpanda 是面向机器的浏览器

Lightpanda 是一个 headless 浏览器,服务对象是机器。人们用它构建 agent 来读取和操作网页,用于大规模数据提取、索引、预渲染和监控等场景。

与爬虫框架不同,Lightpanda(和 curl 及所有浏览器一样)没有内置的 politeness policy。策略由你自己定,而 Lightpanda 让你在浏览器内部执行这些规则,而不是在每个调用它的脚本里各写一遍。

值得先问自己几个问题:

  • 这次会触碰多少页面、涉及多少个 host?
  • 输出是否由模型读取、消耗 token 和 turns?
  • 你跟随的是自己选的链接,还是页面给出来的链接?

下面各节会根据你的回答给出对应的最佳实践。

根据场景选择合适的 Lightpanda 接口

Lightpanda 可执行文件暴露了多种接口,供你控制浏览器。

接口适用场景命令
CLI fetch一次性提取和 shell 管道lightpanda fetch --dump markdown URL
CDP server用 Puppeteer、Playwright 或其他客户端写自定义脚本lightpanda serve
MCP server模型驱动的浏览lightpanda mcp
Agent mode让浏览器直接驱动模型,适合非技术用户lightpanda agent
PandaScript 确定性地重放录制的流程lightpanda run script.js

正确配置浏览器

以下代码片段可应用于所有接口:fetchservemcpagentrun

表明你的身份

无论流量大小,这一点都适用。站点运营方对可识别的流量和不可识别的流量区别对待:在分析中单独归类已知客户端、施加各自的速率限制、并将认识的加入白名单。

--user-agent 会直接替换 user agent 字符串。把你的名称和一个 URL 写进去:

./lightpanda serve --user-agent "MyCompany/1.0 (+https://example.com/bot)"

想了解你的流量在做什么的运营方可以访问那个页面,然后直接联系你,而不是写一条防火墙规则。

--user-agent 会拒绝任何包含 "mozilla" 的值,这意味着无法伪装成 Chrome、Firefox、Safari 或 Edge,因为它们都还带有旧的 Mozilla/5.0 标记。无论你怎么设置,Lightpanda 都会同时发送 Sec-Ch-Ua: "Lightpanda";v="1",确保引擎对任何检查方可见。

用 Web Bot Auth 来证明。user agent 字符串只是一种声明,别的客户端完全可以发同样的值。Web Bot Auth 用签名替代了这种声明:Lightpanda 用 Ed25519 密钥对每个出站请求签名,站点则对照你发布的密钥目录进行验证。Cloudflare、Akamai、Google 和 AWS 都支持签名验证。只需三个参数:--web-bot-auth-key-file--web-bot-auth-keyid--web-bot-auth-domain。我们的 Web Bot Auth 文章 介绍了完整配置方法。

批量抓取时遵守 robots.txt

站点通过 robots.txt 声明哪些路径允许自动化工具访问,格式遵循 RFC 9309。加上 --obey-robots 后,Lightpanda 会在每次请求前检查,每个主机只获取一次该文件,结果在整个会话中共享。

./lightpanda serve --obey-robots --dump markdown https://example.com/some/page

批量抓取页面时记得开启它。被禁止的路径往往正是网站最耗费资源去响应的页面:无限 diff 视图、搜索结果的各种排列组合、每次加载都要查数据库的多维度筛选。网站管理员禁止抓取它们就是因为开销太大。遵守这份列表,是确保自己不造成破坏的最省事方式。

抓取量上来后,控制导航节奏

以事件循环能跑多快就发多快导航的抓取任务,只会拖垮它正在读取的网站。触发限流、CAPTCHA 和封禁是结果,而不是问题本身。

大多数人是在自动化脚本里做节流的,结果就是每个脚本都要重复实现一遍,任何 bug 都会直接砸到目标网站上。PR #3239 把这件事移进了浏览器内部:

./lightpanda serve --http-nav-delay 1000

此后,无论是什么在驱动浏览器,对同一主机的导航请求都会间隔至少一秒。这个限制按主机生效,所以范围广、深度浅的抓取完全不受影响,只有集中打在单点上的负载才会感到它。建议从 1000 ms 起步,再根据情况调整。能平稳跑完一整夜的任务,好过凌晨两点就被封掉的快速任务。

只有顶层导航会被节流,因为如果每个子请求都延迟,页面加载时间就会变得不可预测。另外,节流不等于并发控制:--http-max-host-open 用于限制对单个主机的并发连接数,默认值为 6。

给每个任务一个独立的浏览器

让每个任务都限定在自己的浏览器实例里。这正是我们在AI agent 时代的浏览器安全一文中描述的模型。Lightpanda 能做到这一点而 Chrome 做不到,因为它的启动几乎瞬时完成,每个实例的内存占用也很小。

一个会读取不可信内容、持有会话状态、还能在网上执行操作的任务,会让你暴露在 prompt injection 的风险之下。把浏览器限定在单一任务上,只赋予该任务所需的权限,会更安全。同时建议加上 --block-private-networks,毕竟运行在你内网里的浏览器,就是一个随时可能被利用的 server-side request forgery 隐患。

即使内容完全可信,一个全新实例也没有任何 cookies、存储或残留状态,任务要么从零开始顺利完成,要么干脆利落地失败。

只有 CDP 和 MCP 需要显式配置隔离,其他接口会自动处理。

CDP 服务器。 生命周期由你掌控。用 Puppeteer 或 Playwright 时,为每个任务新建一个浏览器实例,每个实例连接独立的 Lightpanda 进程;也可以在同一个连接内创建独立的 context。

MCP 服务器。 行为取决于你选的模式。默认 stdio 模式为整个会话提供一个浏览器;HTTP 模式(启动时加 --port 3000)则允许你开多个会话,各自拥有独立浏览器。需要按任务隔离就用 HTTP 模式。

最省成本的请求,是你压根没发出去的那个

上面每个参数都会影响你发出的请求,但更大的收益来自少发请求——而这件事取决于你的设计。

  1. 有批量数据源就用批量数据源。 逐页翻网页版 git 平台来重建历史,意味着成百上千次页面加载,每次还得让服务器现场生成 diff。一条 git clone 就能把同样的数据拉到本地,之后查询快如内存操作。同理,有文档化的 API 就别去操作它上面的界面,有 sitemap.xml 就别靠链接爬取来发现页面。
  2. 用搜索 API,别去渲染搜索引擎页面。 Exa、Tavily、Brave Search 等 API 直接返回结果,省去渲染和解析的开销。MCP agent 也可以直接用原生的 search 工具。
  3. 站点让你等一下,就等。 返回 429 或 503 且带 Retry-After 头,说明服务器在说"给我点喘息空间"。读这个头、暂停请求,是你代码该做的事。Lightpanda 不会自动重试,--http-nav-delay 也覆盖不了这种场景:限流意味着你的节奏还是太快了。
  4. 跨运行做缓存。 Lightpanda 的 HTTP 缓存遵循 RFC 9111,通过 If-None-MatchIf-Modified-Since 做重验证,未变化的资源只返回 304、不带 body。默认是关闭的,需要手动指定缓存目录:
./lightpanda serve --http-cache-dir /var/cache/lightpanda
  1. 别抓取你会丢掉的东西。只要文本的话,广告网络、统计信标、跟踪像素一概不需要。--adblock-lists 接收过滤列表,--block-urls 接收自定义匹配规则。外部样式表默认关闭,除非传入 --load-resources stylesheet;但在 agent 模式(接 LLM)下默认加载,让模型能判断页面哪些内容可见。
  2. 别踩进无限 URL 空间。日历、任意版本间的 diff、分面搜索、排序参数——这些都会产生无界 URL,而每个 URL 在对面通常对应一次新的数据库查询。一旦误入其中,运行就永远停不下来,而且整个过程看起来像是一场攻击。
  3. 限制每个站点的深度和广度。提前定好链接跟多深、从一个域名最多保留多少 URL。Linkup 曾就 AI 搜索爬取写过相关内容:不设上限的话,大站点的长尾部分会吃掉大部分预算,却几乎返回不了什么。

流程稳定下来之后,别再反复摸索

模型第一次想通怎么登录、怎么拉报告,那是推理。第一千次,那就是浪费,还多了一次出错的机会。把流程固化成 PandaScript,用 lightpanda run script.js 回放。你不再为反复摸索买单,失败模式也从"看似合理的错误答案"变成了"脚本报错"。

给 agent 的模型,只喂它需要的

模型一旦开始消费输出,瓶颈就不再是带宽,而是上下文。整页倾倒进去既烧 token,又挤掉你真正需要的推理空间。

我们自己量过:决定准确率的关键变量是工具接口,而不是引擎本身。

  1. tree 开始。语义树一次就能拿到角色、可访问名称和交互性,让模型知道这是什么类型的页面、关键内容在哪。LP.getSemanticTree 通过 CDP 实现同样效果。
  2. nodeDetailsfindElement 深入。定位你关心的区域,别把整个文档拉下来。
  3. 然后对该子树调用 markdown传入节点 ID 或选择器即可。有时候整页转 markdown 仍然是对的,但它应该只是兜底方案。

这适用于哪些场景

原始来源: lightpanda

评论 (0)