<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>浏览器自动化 on KnightLi的博客</title>
        <link>https://knightli.com/tags/%E6%B5%8F%E8%A7%88%E5%99%A8%E8%87%AA%E5%8A%A8%E5%8C%96/</link>
        <description>Recent content in 浏览器自动化 on KnightLi的博客</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh-cn</language>
        <lastBuildDate>Sun, 24 May 2026 23:43:35 +0800</lastBuildDate><atom:link href="https://knightli.com/tags/%E6%B5%8F%E8%A7%88%E5%99%A8%E8%87%AA%E5%8A%A8%E5%8C%96/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>browser-harness 的 domain skills 机制：让 AI Agent 不再重复踩网页自动化的坑</title>
        <link>https://knightli.com/2026/05/24/browser-harness-domain-skills-summary/</link>
        <pubDate>Sun, 24 May 2026 23:43:35 +0800</pubDate>
        
        <guid>https://knightli.com/2026/05/24/browser-harness-domain-skills-summary/</guid>
        <description>&lt;p&gt;&lt;code&gt;browser-use/browser-harness&lt;/code&gt; 最有意思的地方，不只是让 AI Agent 能控制真实 Chrome，而是它把网页操作中的经验变成了可以复用的 &lt;code&gt;domain skills&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;这件事很关键。浏览器自动化真正困难的地方，往往不是“能不能点击按钮”，而是每个网站都有自己的细节：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;哪些页面必须登录。&lt;/li&gt;
&lt;li&gt;哪些数据可以直接走 API。&lt;/li&gt;
&lt;li&gt;哪些按钮用普通 DOM 点击无效。&lt;/li&gt;
&lt;li&gt;哪些 iframe、shadow DOM、弹窗会挡住流程。&lt;/li&gt;
&lt;li&gt;哪些选择器稳定，哪些只是临时 class。&lt;/li&gt;
&lt;li&gt;哪些操作涉及账号、支付或不可逆变更，必须让人确认。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果这些经验只留在一次任务日志里，Agent 下次还会重新踩坑。&lt;code&gt;domain skills&lt;/code&gt; 的作用，就是把这些经验沉淀下来，让 Agent 不必每次都像第一次打开网站。&lt;/p&gt;
&lt;h2 id=&#34;domain-skills-是什么&#34;&gt;domain skills 是什么
&lt;/h2&gt;&lt;p&gt;可以把 &lt;code&gt;domain skills&lt;/code&gt; 理解成“给 Agent 看的站点操作手册”。&lt;/p&gt;
&lt;p&gt;它不是普通的用户文档，也不是一次性脚本。它更像一组经过实测的站点级知识：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;这个站点适不适合用浏览器。&lt;/li&gt;
&lt;li&gt;如果有 API，应该优先用哪个 API。&lt;/li&gt;
&lt;li&gt;如果必须操作网页，应该从哪个 URL 进入。&lt;/li&gt;
&lt;li&gt;哪些 DOM 结构、aria-label、按钮行为经过验证。&lt;/li&gt;
&lt;li&gt;哪些常见写法会失败。&lt;/li&gt;
&lt;li&gt;哪些场景要停止并请求人类介入。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这类内容既能被人类审查，也能被 Agent 在任务中读取。它把“临场摸索”变成“可维护经验”。&lt;/p&gt;
&lt;h2 id=&#34;它不是让-agent-盲目点击&#34;&gt;它不是让 Agent 盲目点击
&lt;/h2&gt;&lt;p&gt;一个好的浏览器 Agent，不应该把所有问题都变成打开网页、看截图、点按钮。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;domain skills&lt;/code&gt; 里很重要的一类经验，恰恰是在告诉 Agent：什么时候不要用浏览器。&lt;/p&gt;
&lt;p&gt;比如 ArXiv 这类站点，论文搜索、元数据和摘要可以通过 Atom API 或 HTML meta 标签直接拿到。用 HTTP 请求通常比打开浏览器更快、更稳，也更容易解析。&lt;/p&gt;
&lt;p&gt;GitHub 也是类似思路。仓库、用户、release 数据优先用 REST API；文件内容优先读 &lt;code&gt;raw.githubusercontent.com&lt;/code&gt;；只有 GitHub Trending 这类没有等价 API 的页面，才需要进入浏览器。&lt;/p&gt;
&lt;p&gt;这说明 browser-harness 的思路不是“浏览器万能”，而是把浏览器放在正确位置：当 API、HTTP、静态页面无法解决问题时，再让 Agent 操作真实页面。&lt;/p&gt;
&lt;h2 id=&#34;它记录的是站点级知识&#34;&gt;它记录的是站点级知识
&lt;/h2&gt;&lt;p&gt;传统自动化脚本通常围绕一次任务写，比如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;打开页面 -&amp;gt; 输入关键词 -&amp;gt; 点击按钮 -&amp;gt; 下载文件
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这种脚本可以完成任务，但经验很容易散落在代码里。站点一改版，脚本失效；换一个任务，很多经验也没法复用。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;domain skills&lt;/code&gt; 的粒度更接近站点级知识库。它关心的是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Amazon 搜索结果里哪个容器选择器稳定。&lt;/li&gt;
&lt;li&gt;GitHub 哪些数据应该走 REST API。&lt;/li&gt;
&lt;li&gt;LinkedIn 邀请管理页的按钮 aria-label 有什么差异。&lt;/li&gt;
&lt;li&gt;Shopify Admin 里哪些页面是嵌入式 app。&lt;/li&gt;
&lt;li&gt;Shopify Polaris 输入框为什么不能只用普通 JS 设置 value。&lt;/li&gt;
&lt;li&gt;Browser Use Cloud 的浏览器实例如何创建、列出和清理。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些经验不是一次任务的步骤，而是以后很多任务都会用到的判断依据。&lt;/p&gt;
&lt;h2 id=&#34;例子amazon-商品搜索&#34;&gt;例子：Amazon 商品搜索
&lt;/h2&gt;&lt;p&gt;Amazon 商品搜索的经验，重点不只是“怎么搜索商品”，而是哪些路径更稳定。&lt;/p&gt;
&lt;p&gt;比较可靠的做法是直接使用搜索 URL，而不是每次都打开首页再模拟输入。搜索结果可以从 &lt;code&gt;[data-component-type=&amp;quot;s-search-result&amp;quot;]&lt;/code&gt; 这样的容器中提取。字段提取也有细节：标题、价格、评分、评论数、是否赞助，都有各自更稳的 DOM 来源。&lt;/p&gt;
&lt;p&gt;这种经验对 Agent 很有价值。没有它时，Agent 可能会从截图里猜按钮、反复尝试选择器；有了它之后，Agent 可以直接进入更稳定的数据提取路径。&lt;/p&gt;
&lt;p&gt;更重要的是，这类 skill 还会记录陷阱。例如某些看似可用的选择器，在赞助结果或交叉推荐区域里会误读。这种坑只有实测过才知道。&lt;/p&gt;
&lt;h2 id=&#34;例子linkedin-邀请管理&#34;&gt;例子：LinkedIn 邀请管理
&lt;/h2&gt;&lt;p&gt;LinkedIn 这类站点更接近真实账号工作流，风险也更高。&lt;/p&gt;
&lt;p&gt;在邀请管理页里，Accept 和 Ignore 按钮的 &lt;code&gt;aria-label&lt;/code&gt; 格式不同，不能简单地从一个推导另一个。有些邀请卡片里的 Accept 控件甚至不是 &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt;，而是 &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt;，普通 CDP 点击不一定能触发接受动作。&lt;/p&gt;
&lt;p&gt;这种细节说明，真实网页自动化不是“定位到元素就结束”。按钮标签、事件绑定、软导航、组件实现方式，都会影响操作是否真的生效。&lt;/p&gt;
&lt;p&gt;对 Agent 来说，这类经验还有一个安全含义：涉及社交账号、邀请、消息、发帖的操作，不应该完全托管。skill 可以记录路径和陷阱，但批量接受邀请、对外发送内容、修改账号资料这类动作，最好保留人工确认。&lt;/p&gt;
&lt;h2 id=&#34;例子shopify-admin&#34;&gt;例子：Shopify Admin
&lt;/h2&gt;&lt;p&gt;Shopify Admin 的经验说明了另一个问题：后台系统往往不是一个页面，而是一堆嵌入式应用和复杂组件的组合。&lt;/p&gt;
&lt;p&gt;很多 Shopify app 会运行在 iframe 里。Polaris React 输入框、Web Components、嵌入式 app 的交互方式也不同。某些输入框不能只用 &lt;code&gt;element.value = ...&lt;/code&gt;，需要使用更接近真实键盘输入的 CDP keystrokes。&lt;/p&gt;
&lt;p&gt;这类 skill 的价值在于，它让 Agent 先判断当前页面属于哪类 UI，再选择合适的操作方式。&lt;/p&gt;
&lt;p&gt;同时，Shopify 的经验也强调“能不用浏览器就不用浏览器”：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;只读商品和库存数据，优先用 Storefront API。&lt;/li&gt;
&lt;li&gt;有 Admin API token 时，优先用 Admin API。&lt;/li&gt;
&lt;li&gt;编辑主题代码时，优先用 Shopify CLI。&lt;/li&gt;
&lt;li&gt;只有没有 API、一次性设置、探索后台时，才适合让浏览器介入。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这才是成熟的 Agent 工具选择逻辑。&lt;/p&gt;
&lt;h2 id=&#34;例子browser-use-cloud&#34;&gt;例子：Browser Use Cloud
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;domain skills&lt;/code&gt; 不只服务网页点击，也可以记录围绕浏览器运行时的 API 经验。&lt;/p&gt;
&lt;p&gt;Browser Use Cloud 的经验里，会记录如何通过 REST API 创建 cloud browser、列出正在运行的浏览器、清理 zombie browser、获取 liveUrl 和 cdpUrl 等信息。&lt;/p&gt;
&lt;p&gt;这说明 skill 的边界并不局限于“某个网页按钮怎么点”。只要某类任务会反复出现，而且有稳定做法，就可以沉淀成 skill：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;API 调用方式。&lt;/li&gt;
&lt;li&gt;鉴权头格式。&lt;/li&gt;
&lt;li&gt;请求和响应结构。&lt;/li&gt;
&lt;li&gt;已验证状态码。&lt;/li&gt;
&lt;li&gt;常见失败模式。&lt;/li&gt;
&lt;li&gt;清理和回收资源的方法。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;对 Agent 来说，这些都是可复用能力。&lt;/p&gt;
&lt;h2 id=&#34;为什么这比临场推理更可靠&#34;&gt;为什么这比临场推理更可靠
&lt;/h2&gt;&lt;p&gt;很多人期待大模型每次都能“自己看懂网页”。但真实任务里，只靠临场推理并不稳定。&lt;/p&gt;
&lt;p&gt;原因很简单：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;网页 UI 经常变化。&lt;/li&gt;
&lt;li&gt;同一按钮可能有多种实现。&lt;/li&gt;
&lt;li&gt;看得见不代表点得动。&lt;/li&gt;
&lt;li&gt;能点击不代表操作真的生效。&lt;/li&gt;
&lt;li&gt;有些任务本来就应该用 API，而不是浏览器。&lt;/li&gt;
&lt;li&gt;有些操作需要人类确认，不能让模型自己决定。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;domain skills&lt;/code&gt; 把这些经验写成文件后，有几个好处：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;人类可以 review。&lt;/li&gt;
&lt;li&gt;错误经验可以修正。&lt;/li&gt;
&lt;li&gt;同一站点的经验可以持续积累。&lt;/li&gt;
&lt;li&gt;新 Agent 可以直接继承旧经验。&lt;/li&gt;
&lt;li&gt;临时任务发现可以变成长期知识。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这比把一切都塞进 prompt 或聊天上下文更稳。&lt;/p&gt;
&lt;h2 id=&#34;团队可以怎么用&#34;&gt;团队可以怎么用
&lt;/h2&gt;&lt;p&gt;如果把 browser-harness 用在团队里，&lt;code&gt;domain skills&lt;/code&gt; 可以变成一种轻量自动化知识库。&lt;/p&gt;
&lt;p&gt;比较适合沉淀的内容包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;内部后台的登录后路径。&lt;/li&gt;
&lt;li&gt;报表导出流程。&lt;/li&gt;
&lt;li&gt;常见弹窗处理方式。&lt;/li&gt;
&lt;li&gt;哪些按钮需要人工确认。&lt;/li&gt;
&lt;li&gt;哪些页面有 API 替代方案。&lt;/li&gt;
&lt;li&gt;哪些选择器经过实测可靠。&lt;/li&gt;
&lt;li&gt;哪些任务不允许 Agent 自动执行。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这类知识不必一开始就很完整。更实际的做法是从低风险、高频、可回滚的流程开始：先让 Agent 做只读、下载、整理、检查类任务。等流程稳定后，再把经验整理成 skill。&lt;/p&gt;
&lt;p&gt;对团队管理者来说，skill 文件还有一个好处：它让自动化边界变得可见。你可以审查 Agent 知道什么、能做什么、应该停在哪里。&lt;/p&gt;
&lt;h2 id=&#34;需要注意的边界&#34;&gt;需要注意的边界
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;domain skills&lt;/code&gt; 能提高 Agent 成功率，但它不应该让高风险操作完全自动化。&lt;/p&gt;
&lt;p&gt;几个边界要守住：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不记录密码、Cookie、token、客户数据和内部敏感 URL。&lt;/li&gt;
&lt;li&gt;支付、删除、批量提交、账号变更、对外发布内容，要保留人工确认。&lt;/li&gt;
&lt;li&gt;skill 要写明验证日期和适用范围。&lt;/li&gt;
&lt;li&gt;站点改版后，要允许 skill 失效并重新验证。&lt;/li&gt;
&lt;li&gt;不要把绕过风控、规避平台限制当成目标。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;换句话说，domain skill 是让 Agent 更稳，不是让 Agent 无限制地做事。&lt;/p&gt;
&lt;h2 id=&#34;简单结论&#34;&gt;简单结论
&lt;/h2&gt;&lt;p&gt;browser-harness 的 &lt;code&gt;domain skills&lt;/code&gt; 机制说明了一件事：AI Agent 的浏览器自动化，不能只靠模型临场发挥。&lt;/p&gt;
&lt;p&gt;一个可用的浏览器 Agent，至少需要三层能力：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;底层控制能力：截图、点击、输入、下载、CDP、HTTP。&lt;/li&gt;
&lt;li&gt;站点级知识：API 优先级、稳定选择器、组件陷阱、登录边界。&lt;/li&gt;
&lt;li&gt;人类安全规则：凭据不交给模型，高风险操作要确认，敏感信息不写进 skill。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;domain skills&lt;/code&gt; 补的是第二层。它让 Agent 带着验证过的经验进入网页任务，而不是每次都重新摸索。&lt;/p&gt;
&lt;p&gt;参考资料：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;browser-harness domain skills：&lt;a class=&#34;link&#34; href=&#34;https://github.com/browser-use/browser-harness/tree/main/agent-workspace/domain-skills&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/browser-use/browser-harness/tree/main/agent-workspace/domain-skills&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Amazon product-search skill：&lt;a class=&#34;link&#34; href=&#34;https://github.com/browser-use/browser-harness/blob/main/agent-workspace/domain-skills/amazon/product-search.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/browser-use/browser-harness/blob/main/agent-workspace/domain-skills/amazon/product-search.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;ArXiv scraping skill：&lt;a class=&#34;link&#34; href=&#34;https://github.com/browser-use/browser-harness/blob/main/agent-workspace/domain-skills/arxiv/scraping.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/browser-use/browser-harness/blob/main/agent-workspace/domain-skills/arxiv/scraping.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;GitHub scraping skill：&lt;a class=&#34;link&#34; href=&#34;https://github.com/browser-use/browser-harness/blob/main/agent-workspace/domain-skills/github/scraping.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/browser-use/browser-harness/blob/main/agent-workspace/domain-skills/github/scraping.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;LinkedIn invitation-manager skill：&lt;a class=&#34;link&#34; href=&#34;https://github.com/browser-use/browser-harness/blob/main/agent-workspace/domain-skills/linkedin/invitation-manager.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/browser-use/browser-harness/blob/main/agent-workspace/domain-skills/linkedin/invitation-manager.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Shopify admin skill：&lt;a class=&#34;link&#34; href=&#34;https://github.com/browser-use/browser-harness/blob/main/agent-workspace/domain-skills/shopify-admin/README.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/browser-use/browser-harness/blob/main/agent-workspace/domain-skills/shopify-admin/README.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Browser Use Cloud skill：&lt;a class=&#34;link&#34; href=&#34;https://github.com/browser-use/browser-harness/blob/main/agent-workspace/domain-skills/browser-use-cloud/cloud.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/browser-use/browser-harness/blob/main/agent-workspace/domain-skills/browser-use-cloud/cloud.md&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>browser-harness、Playwright、Puppeteer 怎么选？浏览器自动化工具对比</title>
        <link>https://knightli.com/2026/05/24/browser-harness-playwright-puppeteer-comparison/</link>
        <pubDate>Sun, 24 May 2026 17:51:28 +0800</pubDate>
        
        <guid>https://knightli.com/2026/05/24/browser-harness-playwright-puppeteer-comparison/</guid>
        <description>&lt;p&gt;在浏览器自动化和自动化测试领域，&lt;code&gt;Playwright&lt;/code&gt; 和 &lt;code&gt;Puppeteer&lt;/code&gt; 是最常被拿来比较的两个工具。它们都可以控制浏览器、点击页面、抓取内容、生成截图或 PDF，也都和 Chrome DevTools Protocol 有很深关系。&lt;/p&gt;
&lt;p&gt;但如果把 &lt;code&gt;browser-use/browser-harness&lt;/code&gt; 放进来，问题就不只是“哪个测试框架更强”，而是变成了两类工具的对比：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Playwright&lt;/code&gt; / &lt;code&gt;Puppeteer&lt;/code&gt;：面向人类工程师写确定性脚本。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;browser-harness&lt;/code&gt;：面向 AI Agent 操作真实浏览器。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;前者适合测试、爬虫和工程化自动化；后者更像给 Claude Code、Codex CLI、Gemini 这类 Agent 准备的浏览器控制层。&lt;/p&gt;
&lt;h2 id=&#34;playwright-和-puppeteer-的关系&#34;&gt;Playwright 和 Puppeteer 的关系
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;Puppeteer&lt;/code&gt; 最早由 Google Chrome 团队推出，天然服务于 Chromium 和 Chrome 自动化。它的 API 简洁，生态成熟，特别适合围绕 Chrome 做截图、PDF、页面抓取和轻量自动化。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Playwright&lt;/code&gt; 由微软维护，背后团队和早期 Puppeteer 有很深渊源。它吸收了 Puppeteer 的很多经验，同时把跨浏览器、自动等待、上下文隔离、测试报告和调试工具链做得更完整。&lt;/p&gt;
&lt;p&gt;简单说：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;只围绕 Chrome 做轻量任务，&lt;code&gt;Puppeteer&lt;/code&gt; 仍然很顺手。&lt;/li&gt;
&lt;li&gt;做跨浏览器 E2E 测试、复杂 SPA 自动化和团队测试工程，&lt;code&gt;Playwright&lt;/code&gt; 通常更合适。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;核心区别总览&#34;&gt;核心区别总览
&lt;/h2&gt;&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;维度&lt;/th&gt;
          &lt;th&gt;Puppeteer&lt;/th&gt;
          &lt;th&gt;Playwright&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;主导方&lt;/td&gt;
          &lt;td&gt;Google&lt;/td&gt;
          &lt;td&gt;Microsoft&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;浏览器支持&lt;/td&gt;
          &lt;td&gt;主要面向 Chrome / Chromium&lt;/td&gt;
          &lt;td&gt;Chromium、Firefox、WebKit&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;语言支持&lt;/td&gt;
          &lt;td&gt;主要是 JavaScript / TypeScript&lt;/td&gt;
          &lt;td&gt;JavaScript / TypeScript、Python、Java、.NET&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;自动等待&lt;/td&gt;
          &lt;td&gt;需要更多显式等待&lt;/td&gt;
          &lt;td&gt;Locator 和 auto-waiting 更完整&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;多上下文隔离&lt;/td&gt;
          &lt;td&gt;支持，但不是最突出的优势&lt;/td&gt;
          &lt;td&gt;BrowserContext 体验很强&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;工具链&lt;/td&gt;
          &lt;td&gt;简洁、成熟、偏基础&lt;/td&gt;
          &lt;td&gt;Codegen、Trace Viewer、测试报告更完整&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;典型场景&lt;/td&gt;
          &lt;td&gt;Chrome 自动化、截图、PDF、轻量抓取&lt;/td&gt;
          &lt;td&gt;跨浏览器 E2E 测试、复杂前端应用自动化&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;浏览器支持&#34;&gt;浏览器支持
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;Puppeteer&lt;/code&gt; 的优势在 Chrome。它和 Chromium 结合紧密，如果你的目标就是控制 Chrome、生成 PDF、截图、跑简单爬虫，Puppeteer 的心智负担很低。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Playwright&lt;/code&gt; 的优势在跨浏览器。它原生支持 Chromium、Firefox 和 WebKit。WebKit 这一点很关键，因为很多 Safari 相关问题不能只靠 Chrome 测出来。对需要覆盖桌面端、移动端和不同浏览器内核的应用来说，Playwright 更适合作为主力工具。&lt;/p&gt;
&lt;p&gt;这也是两者选择的第一道分界线：只看 Chrome，可以用 Puppeteer；要认真做跨浏览器测试，优先 Playwright。&lt;/p&gt;
&lt;h2 id=&#34;自动等待和稳定性&#34;&gt;自动等待和稳定性
&lt;/h2&gt;&lt;p&gt;浏览器自动化最烦人的问题，往往不是“不会点击”，而是页面还没准备好。元素可能还没挂到 DOM，可能被遮挡，可能正在动画中，可能按钮还是 disabled。&lt;/p&gt;
&lt;p&gt;Puppeteer 里经常会写：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;page&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;waitForSelector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;#submit-btn&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;page&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;click&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;#submit-btn&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这没有问题，但等待逻辑需要工程师自己想清楚。页面越复杂，脚本里越容易出现各种 &lt;code&gt;waitForSelector&lt;/code&gt;、&lt;code&gt;waitForTimeout&lt;/code&gt; 和重试逻辑。&lt;/p&gt;
&lt;p&gt;Playwright 的 Locator 机制和自动等待更完整：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;page&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;locator&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;#submit-btn&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;click&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;在点击之前，Playwright 会自动检查元素是否可见、可操作、稳定、没有被遮挡，并在合理时间内重试。这对 React、Vue、Next.js 这类异步渲染很多的现代 Web 应用尤其重要，可以明显减少 flaky test。&lt;/p&gt;
&lt;h2 id=&#34;多账号和上下文隔离&#34;&gt;多账号和上下文隔离
&lt;/h2&gt;&lt;p&gt;如果你要模拟多个用户，或者想让多个任务共享同一个浏览器进程但隔离 Cookie、LocalStorage 和 Session，&lt;code&gt;BrowserContext&lt;/code&gt; 就很重要。&lt;/p&gt;
&lt;p&gt;Puppeteer 也支持上下文隔离，但 Playwright 把这件事做成了核心能力。你可以在一个浏览器实例里快速创建多个独立 context，每个 context 像一个干净的浏览器环境，却不需要反复启动完整浏览器进程。&lt;/p&gt;
&lt;p&gt;这对这些场景很有价值：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;多账号并发测试。&lt;/li&gt;
&lt;li&gt;多角色协作流程测试。&lt;/li&gt;
&lt;li&gt;电商、IM、协作文档等多用户场景。&lt;/li&gt;
&lt;li&gt;需要隔离 Cookie 和登录态的爬取任务。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;工具链差异&#34;&gt;工具链差异
&lt;/h2&gt;&lt;p&gt;Playwright 是更“工程化”的方案。它内置了很多测试开发会用到的工具：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;codegen&lt;/code&gt;：在网页上操作，自动生成脚本。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Trace Viewer&lt;/code&gt;：失败后回看每一步的截图、DOM、网络请求和 console 日志。&lt;/li&gt;
&lt;li&gt;Test Runner：支持断言、并行、重试、报告和项目矩阵。&lt;/li&gt;
&lt;li&gt;Locator：支持按文本、角色、label、test id 等方式定位元素。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Puppeteer 则更像一个轻量浏览器控制库。它不臃肿，API 直接，适合嵌入脚本、服务端任务和自定义自动化流程。&lt;/p&gt;
&lt;p&gt;如果你要搭企业级测试体系，Playwright 的配套工具会省很多事。如果你只是要写一个 Node.js 脚本，把网页转 PDF 或定时截图，Puppeteer 反而更干脆。&lt;/p&gt;
&lt;h2 id=&#34;browser-harness-放在哪里&#34;&gt;browser-harness 放在哪里
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;browser-harness&lt;/code&gt; 和 Playwright、Puppeteer 不是同一类工具。&lt;/p&gt;
&lt;p&gt;Playwright 和 Puppeteer 主要假设“人类写脚本”。人类工程师要决定选择器、等待条件、断言逻辑和异常处理。它们追求的是确定性：同样的脚本，在同样的页面状态下，应该给出同样的结果。&lt;/p&gt;
&lt;p&gt;browser-harness 主要假设“AI Agent 操作浏览器”。它的目标不是提供一套巨大的高级 API，而是通过 CDP 连接真实 Chrome，把截图、坐标点击、DOM、网络请求和 helper 暴露给 Agent。Agent 可以观察页面、判断下一步、遇到缺能力时补 helper，再把站点经验沉淀成 skill。&lt;/p&gt;
&lt;p&gt;这就让它更适合开放任务：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;登录后台后下载账单。&lt;/li&gt;
&lt;li&gt;在内部系统里填一组表单。&lt;/li&gt;
&lt;li&gt;处理经常改版的 OA 或 SaaS 页面。&lt;/li&gt;
&lt;li&gt;按用户目标探索页面，而不是执行固定脚本。&lt;/li&gt;
&lt;li&gt;让 Claude Code、Codex CLI 这类工具拥有浏览器操作能力。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;三者核心对比&#34;&gt;三者核心对比
&lt;/h2&gt;&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;维度&lt;/th&gt;
          &lt;th&gt;Puppeteer&lt;/th&gt;
          &lt;th&gt;Playwright&lt;/th&gt;
          &lt;th&gt;browser-harness&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;面向对象&lt;/td&gt;
          &lt;td&gt;人类工程师&lt;/td&gt;
          &lt;td&gt;人类工程师和测试团队&lt;/td&gt;
          &lt;td&gt;AI Agent&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;主要目标&lt;/td&gt;
          &lt;td&gt;控制 Chrome&lt;/td&gt;
          &lt;td&gt;稳定跨浏览器自动化&lt;/td&gt;
          &lt;td&gt;让 Agent 操作真实浏览器&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;脚本方式&lt;/td&gt;
          &lt;td&gt;手写 JS/TS 自动化&lt;/td&gt;
          &lt;td&gt;手写脚本 + 测试框架&lt;/td&gt;
          &lt;td&gt;用户下目标，Agent 分步执行&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;元素定位&lt;/td&gt;
          &lt;td&gt;CSS、XPath、DOM API&lt;/td&gt;
          &lt;td&gt;Locator、文本、角色、CSS&lt;/td&gt;
          &lt;td&gt;截图视觉、坐标、DOM、CDP&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;等待机制&lt;/td&gt;
          &lt;td&gt;更多手动控制&lt;/td&gt;
          &lt;td&gt;自动等待很强&lt;/td&gt;
          &lt;td&gt;由 Agent 观察和调整&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;浏览器环境&lt;/td&gt;
          &lt;td&gt;通常启动自动化浏览器&lt;/td&gt;
          &lt;td&gt;通常启动测试浏览器&lt;/td&gt;
          &lt;td&gt;常连接真实 Chrome&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;最适合&lt;/td&gt;
          &lt;td&gt;Chrome 脚本、截图、PDF、轻量抓取&lt;/td&gt;
          &lt;td&gt;E2E 测试、跨浏览器验证、复杂 SPA&lt;/td&gt;
          &lt;td&gt;AI 助手、开放网页任务、真实账号工作流&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;代码体感对比&#34;&gt;代码体感对比
&lt;/h2&gt;&lt;p&gt;Puppeteer 更像直接控制 Chrome：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;puppeteer&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;puppeteer&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;browser&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;puppeteer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;launch&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;page&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;browser&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;newPage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;page&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;goto&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;https://example.com&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;page&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;waitForSelector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;#submit-btn&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;page&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;click&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;#submit-btn&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;browser&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;close&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;})();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Playwright 更强调 Locator 和自动等待：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;chromium&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;playwright&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;browser&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;chromium&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;launch&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;page&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;browser&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;newPage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;page&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;goto&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;https://example.com&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;page&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;locator&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;#submit-btn&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;click&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;browser&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;close&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;})();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;browser-harness 的使用体感则完全不同。你通常不是写完整脚本，而是在 Agent 环境里下达目标：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;帮我打开后台，下载上个月的账单，并整理成报销用的文件。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Agent 会借助 browser-harness 反复执行类似流程：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;截图，理解当前页面。&lt;/li&gt;
&lt;li&gt;点击某个坐标或定位某个元素。&lt;/li&gt;
&lt;li&gt;输入文字、上传文件、下载文件。&lt;/li&gt;
&lt;li&gt;遇到弹窗时判断如何关闭。&lt;/li&gt;
&lt;li&gt;缺少 helper 时补充代码。&lt;/li&gt;
&lt;li&gt;把可复用流程沉淀为 domain skill。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这不是传统测试脚本的写法，而是浏览器 Agent 的工作方式。&lt;/p&gt;
&lt;h2 id=&#34;怎么选&#34;&gt;怎么选
&lt;/h2&gt;&lt;p&gt;选择 &lt;code&gt;Puppeteer&lt;/code&gt;，通常是因为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;项目主要跑在 Node.js 里。&lt;/li&gt;
&lt;li&gt;只需要 Chrome 或 Chromium。&lt;/li&gt;
&lt;li&gt;任务是截图、PDF、简单页面抓取或轻量自动化。&lt;/li&gt;
&lt;li&gt;你希望 API 简洁，依赖少，自己控制更多细节。&lt;/li&gt;
&lt;li&gt;你对 Chrome DevTools Protocol 有较深依赖。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;选择 &lt;code&gt;Playwright&lt;/code&gt;，通常是因为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;你要做标准 UI 自动化或 E2E 测试。&lt;/li&gt;
&lt;li&gt;需要覆盖 Chromium、Firefox 和 WebKit。&lt;/li&gt;
&lt;li&gt;团队主语言可能是 Python、Java 或 C#。&lt;/li&gt;
&lt;li&gt;页面是复杂 SPA，异步状态多，容易出现 flaky test。&lt;/li&gt;
&lt;li&gt;你需要 codegen、Trace Viewer、测试报告和并行测试。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;选择 &lt;code&gt;browser-harness&lt;/code&gt;，通常是因为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;你在开发或使用 AI Agent。&lt;/li&gt;
&lt;li&gt;你希望模型像人一样操作真实浏览器。&lt;/li&gt;
&lt;li&gt;任务步骤不固定，需要边看页面边判断。&lt;/li&gt;
&lt;li&gt;目标网站经常改版，或者弹窗、iframe、shadow DOM 很多。&lt;/li&gt;
&lt;li&gt;你想把真实网页工作流交给 Claude Code、Codex CLI 等工具处理。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;简单结论&#34;&gt;简单结论
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;Playwright&lt;/code&gt; 和 &lt;code&gt;Puppeteer&lt;/code&gt; 是浏览器自动化工具，核心是让人写出可靠脚本。两者相比，Puppeteer 更轻、更贴近 Chrome；Playwright 更完整、更适合跨浏览器测试和复杂前端应用。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;browser-harness&lt;/code&gt; 则是另一个方向：它不是为了取代 Playwright 或 Puppeteer 写测试，而是为了让 AI Agent 接管真实浏览器。它牺牲了一部分传统脚本的确定性，换来更强的开放任务适应能力。&lt;/p&gt;
&lt;p&gt;所以答案不是三选一，而是按任务分层：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;测试工程：优先 Playwright。&lt;/li&gt;
&lt;li&gt;Chrome 轻量脚本：Puppeteer 很合适。&lt;/li&gt;
&lt;li&gt;AI Agent 上网办事：看 browser-harness。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;参考资料：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;browser-use/browser-harness：&lt;a class=&#34;link&#34; href=&#34;https://github.com/browser-use/browser-harness&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/browser-use/browser-harness&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Playwright 官方文档：&lt;a class=&#34;link&#34; href=&#34;https://playwright.dev/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://playwright.dev/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Puppeteer 官方文档：&lt;a class=&#34;link&#34; href=&#34;https://pptr.dev/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://pptr.dev/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Chrome DevTools Protocol：&lt;a class=&#34;link&#34; href=&#34;https://chromedevtools.github.io/devtools-protocol/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://chromedevtools.github.io/devtools-protocol/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>browser-harness 是什么？AI Agent 接管真实 Chrome 的浏览器自动化工具</title>
        <link>https://knightli.com/2026/05/24/browser-use-browser-harness-ai-agent-browser-automation/</link>
        <pubDate>Sun, 24 May 2026 17:19:54 +0800</pubDate>
        
        <guid>https://knightli.com/2026/05/24/browser-use-browser-harness-ai-agent-browser-automation/</guid>
        <description>&lt;p&gt;&lt;code&gt;browser-use/browser-harness&lt;/code&gt; 是一个面向 AI Agent 的浏览器控制工具。它的目标不是再做一层复杂的自动化框架，而是把大模型直接连到真实 Chrome，通过 CDP 完成浏览、点击、截图、下载、上传和表单操作。&lt;/p&gt;
&lt;p&gt;项目 README 对自己的定位很明确：用一层很薄、可编辑的 CDP harness，让 LLM 直接连接真实浏览器；当任务中缺少 helper 时，Agent 可以在执行过程中补上代码，并把可复用经验沉淀成 domain skills。&lt;/p&gt;
&lt;p&gt;这类工具值得关注，是因为浏览器仍然是很多真实工作的入口：后台系统、SaaS 面板、电商页面、招聘网站、CRM、报销系统、云控制台、文档平台，往往没有稳定 API，或者 API 权限比网页权限更难拿到。让 Agent 能可靠地操作浏览器，本质上是在补齐“最后一公里”的自动化能力。&lt;/p&gt;
&lt;h2 id=&#34;browser-harness-是什么&#34;&gt;browser-harness 是什么
&lt;/h2&gt;&lt;p&gt;从结构看，browser-harness 更像一个给 Agent 用的浏览器运行时，而不是普通用户手动点击的浏览器插件。&lt;/p&gt;
&lt;p&gt;它的核心思路有几个：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;直接连接 Chrome 或 Chromium 浏览器。&lt;/li&gt;
&lt;li&gt;通过 CDP WebSocket 操作页面。&lt;/li&gt;
&lt;li&gt;让 Agent 用截图、坐标点击、DOM、网络请求和原始 CDP 组合完成任务。&lt;/li&gt;
&lt;li&gt;把任务相关 helper 放在 &lt;code&gt;agent-workspace/agent_helpers.py&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;把站点相关经验沉淀到 &lt;code&gt;agent-workspace/domain-skills/&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;保持核心很薄，避免做成庞大的自动化平台。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;README 中提到，项目核心架构大约是 4 个核心文件、约 1000 行代码，主要包括 &lt;code&gt;install.md&lt;/code&gt;、&lt;code&gt;SKILL.md&lt;/code&gt;、&lt;code&gt;src/browser_harness/&lt;/code&gt;、&lt;code&gt;agent-workspace/agent_helpers.py&lt;/code&gt; 和 &lt;code&gt;agent-workspace/domain-skills/&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;这种设计的重点不是“内置所有网站能力”，而是给 Agent 一个足够贴近真实浏览器的操作层，让它在具体任务里补齐缺失能力。&lt;/p&gt;
&lt;h2 id=&#34;它和传统浏览器自动化有什么不同&#34;&gt;它和传统浏览器自动化有什么不同
&lt;/h2&gt;&lt;p&gt;传统浏览器自动化通常围绕测试框架展开，例如 Playwright、Selenium 或 Puppeteer。它们适合写确定性的测试脚本：打开页面、定位元素、点击、断言结果。&lt;/p&gt;
&lt;p&gt;browser-harness 面向的是另一类任务：用户说一句目标，Agent 自己探索页面、判断状态、处理弹窗、补 helper、复用站点经验。它强调的是交互过程中的适应性。&lt;/p&gt;
&lt;p&gt;差异可以这样理解：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Playwright 更适合人写脚本，Agent 执行脚本。&lt;/li&gt;
&lt;li&gt;browser-harness 更适合 Agent 边看页面边行动。&lt;/li&gt;
&lt;li&gt;传统自动化偏固定流程。&lt;/li&gt;
&lt;li&gt;browser-harness 偏开放任务。&lt;/li&gt;
&lt;li&gt;传统脚本常依赖选择器。&lt;/li&gt;
&lt;li&gt;browser-harness 鼓励先截图、再按可见界面行动，必要时再退回 DOM 或 CDP。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这并不意味着它要替代 Playwright。对稳定测试来说，Playwright 仍然更成熟。browser-harness 的价值在于把真实网页变成 Agent 可操作的环境，尤其适合那些页面结构复杂、步骤不固定、需要临场判断的任务。&lt;/p&gt;
&lt;h2 id=&#34;为什么强调真实-chrome&#34;&gt;为什么强调真实 Chrome
&lt;/h2&gt;&lt;p&gt;很多浏览器 Agent 工具会使用隔离的无头浏览器。这样部署简单，也适合批量任务，但它有一个现实问题：用户真实工作里的登录态、扩展、历史记录、书签和日常浏览器环境并不一定能直接复用。&lt;/p&gt;
&lt;p&gt;browser-harness 支持连接本机 Chrome，也支持 Browser Use cloud browser。对本机浏览器，它提供两种方式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;通过 &lt;code&gt;chrome://inspect/#remote-debugging&lt;/code&gt; 允许当前 Chrome 实例被连接。&lt;/li&gt;
&lt;li&gt;用 &lt;code&gt;--remote-debugging-port=9222 --user-data-dir=...&lt;/code&gt; 启动一个隔离 profile。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果要让 Agent 帮你处理真实账号里的任务，项目文档更倾向于第一种方式，因为它能复用日常 Chrome 的登录态、扩展和书签。如果要做无人值守自动化，或者不希望被弹窗打断，则更适合使用隔离 profile 或云浏览器。&lt;/p&gt;
&lt;p&gt;这里的取舍很清楚：真实浏览器更贴近用户工作流，但安全边界也更敏感；隔离浏览器更适合自动化，但需要重新处理登录和环境。&lt;/p&gt;
&lt;h2 id=&#34;可编辑-helper-和-domain-skills&#34;&gt;可编辑 helper 和 domain skills
&lt;/h2&gt;&lt;p&gt;browser-harness 最有意思的地方，是它把“Agent 会学到什么”设计进了项目结构。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;agent-workspace/agent_helpers.py&lt;/code&gt; 用来放任务中临时补出来的 helper。比如 Agent 做文件上传时发现现有能力不够，可以补一个稳定的上传函数；下次再遇到类似页面，就不用从零开始。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;agent-workspace/domain-skills/&lt;/code&gt; 则用来放站点级经验。README 里举的方向包括 LinkedIn outreach、Amazon 下单、报销系统等。项目建议不要手写这些 skill，而是让 Agent 在真实任务中发现可复用流程后再生成，这样更贴近实际页面行为。&lt;/p&gt;
&lt;p&gt;这个思路很适合浏览器自动化。因为网页自动化的难点往往不是“怎么点击按钮”，而是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;某个网站的登录后页面怎么跳转。&lt;/li&gt;
&lt;li&gt;哪些弹窗会挡住主流程。&lt;/li&gt;
&lt;li&gt;哪些 selector 稳定，哪些只是临时样式名。&lt;/li&gt;
&lt;li&gt;上传、下载、iframe、shadow DOM、跨域组件怎么处理。&lt;/li&gt;
&lt;li&gt;某个后台系统有哪些隐藏等待和异步状态。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些知识如果只留在一次运行日志里，很快就会丢掉。把它们沉淀成 domain skills，才可能让 Agent 越用越顺。&lt;/p&gt;
&lt;h2 id=&#34;适合哪些场景&#34;&gt;适合哪些场景
&lt;/h2&gt;&lt;p&gt;browser-harness 更适合以下任务：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;帮用户操作真实网页后台。&lt;/li&gt;
&lt;li&gt;在没有 API 的系统里完成重复流程。&lt;/li&gt;
&lt;li&gt;登录态依赖强的个人或企业网页任务。&lt;/li&gt;
&lt;li&gt;需要截图判断页面状态的复杂交互。&lt;/li&gt;
&lt;li&gt;Agent 需要在执行中补工具、补站点经验。&lt;/li&gt;
&lt;li&gt;多个子 Agent 各自使用独立浏览器执行任务。&lt;/li&gt;
&lt;li&gt;研究浏览器 Agent 的运行时设计。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;具体例子包括：整理网页表格、提交内部系统表单、下载账单、上传文件、处理报销流程、检查订单状态、在 SaaS 控制台里配置资源、从登录后的网页提取信息。&lt;/p&gt;
&lt;p&gt;如果任务只是抓取静态网页，未必需要浏览器。项目自己的 &lt;code&gt;SKILL.md&lt;/code&gt; 也提到，静态页面可以直接用 HTTP 批量获取；浏览器应该留给真正需要页面状态、登录态和交互的场景。&lt;/p&gt;
&lt;h2 id=&#34;需要注意的风险&#34;&gt;需要注意的风险
&lt;/h2&gt;&lt;p&gt;让 AI Agent 接管真实 Chrome，很强，也很危险。&lt;/p&gt;
&lt;p&gt;第一，权限边界要清楚。真实 Chrome 里可能有邮箱、支付后台、云控制台、公司系统和个人账号。Agent 一旦能操作浏览器，就等于获得了这些网页权限的一部分。&lt;/p&gt;
&lt;p&gt;第二，不要把凭据交给模型。遇到登录页、支付验证、二次确认等敏感步骤，应该让用户自己处理。Agent 可以等待登录完成，但不应该从截图里读取或输入密码、验证码、支付信息。&lt;/p&gt;
&lt;p&gt;第三，自动化不等于可托管。很多网页任务看似简单，但中间可能出现风控、误点击、数据删除、批量提交、不可逆操作。适合先从只读、低风险、可回滚的流程开始。&lt;/p&gt;
&lt;p&gt;第四，domain skills 需要避免泄露隐私。站点经验可以公开，但不要把账号、内部 URL、客户数据、坐标流水账或一次性任务细节写进去。&lt;/p&gt;
&lt;p&gt;第五，真实浏览器连接方式要谨慎选择。如果要复用日常登录态，使用当前 Chrome 很方便；如果要跑长时间自动化，隔离 profile 或云浏览器更可控。&lt;/p&gt;
&lt;h2 id=&#34;对-ai-agent-工具的意义&#34;&gt;对 AI Agent 工具的意义
&lt;/h2&gt;&lt;p&gt;browser-harness 代表了一种很务实的 Agent 工具路线：少做平台，多给模型一个可以直接触达真实环境的接口。&lt;/p&gt;
&lt;p&gt;过去很多 Agent 失败在两端。一端是模型会推理，但摸不到真实页面；另一端是自动化框架很强，但需要人先把流程写死。browser-harness 试图把这两端接起来：浏览器负责真实世界的状态，Agent 负责观察、判断和补工具。&lt;/p&gt;
&lt;p&gt;这也是“自我改进 harness”的意义。它不是说 Agent 会神奇地变聪明，而是把可复用的操作经验放到项目结构里，让下一次任务少走弯路。&lt;/p&gt;
&lt;p&gt;对开发者来说，browser-harness 的价值主要在三个层面：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;作为个人 Agent 的浏览器控制层。&lt;/li&gt;
&lt;li&gt;作为研究浏览器自动化和 Agent 工作流的样本。&lt;/li&gt;
&lt;li&gt;作为把网页流程变成可复用技能的实验框架。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;它不是所有浏览器自动化问题的答案，但它给出了一个清晰方向：当 Agent 真正要帮人做事时，工具层不只要能调用 API，也要能理解和操作人类每天使用的网页界面。&lt;/p&gt;
&lt;h2 id=&#34;简单结论&#34;&gt;简单结论
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;browser-use/browser-harness&lt;/code&gt; 值得关注，不是因为它包装了多少高级功能，而是因为它把浏览器 Agent 的几个关键问题摆在了台面上：真实 Chrome、CDP、截图驱动、可编辑 helper、站点技能沉淀，以及用户权限边界。&lt;/p&gt;
&lt;p&gt;如果你只是写稳定端到端测试，继续用 Playwright 或 Selenium 就很好。如果你想让 Codex、Claude Code 这类 Agent 直接帮你处理真实网页任务，browser-harness 提供了一个更贴近 Agent 工作方式的入口。&lt;/p&gt;
&lt;p&gt;真正使用时，建议从低风险任务开始：先让它读页面、截图、提取信息，再逐步尝试点击和提交。等你确认它能稳定识别页面状态，再考虑让它接管更长的流程。&lt;/p&gt;
&lt;p&gt;参考资料：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GitHub 项目：&lt;a class=&#34;link&#34; href=&#34;https://github.com/browser-use/browser-harness&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/browser-use/browser-harness&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;README：&lt;a class=&#34;link&#34; href=&#34;https://github.com/browser-use/browser-harness/blob/main/README.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/browser-use/browser-harness/blob/main/README.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;安装文档：&lt;a class=&#34;link&#34; href=&#34;https://github.com/browser-use/browser-harness/blob/main/install.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/browser-use/browser-harness/blob/main/install.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;使用说明：&lt;a class=&#34;link&#34; href=&#34;https://github.com/browser-use/browser-harness/blob/main/SKILL.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/browser-use/browser-harness/blob/main/SKILL.md&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>CloakBrowser 是什么？给 Playwright 和 Puppeteer 换一个更像真实用户的浏览器</title>
        <link>https://knightli.com/2026/05/19/cloakbrowser-stealth-chromium-browser-automation/</link>
        <pubDate>Tue, 19 May 2026 10:56:50 +0800</pubDate>
        
        <guid>https://knightli.com/2026/05/19/cloakbrowser-stealth-chromium-browser-automation/</guid>
        <description>&lt;p&gt;&lt;code&gt;CloakHQ/CloakBrowser&lt;/code&gt; 是一个面向浏览器自动化的开源项目。它不是普通的 Playwright 配置，也不是单纯注入一段 JavaScript，而是围绕自定义 Chromium 二进制构建，让浏览器指纹、WebGL、Canvas、音频、字体、GPU、屏幕信息、WebRTC、网络时序等信号更接近真实浏览器。&lt;/p&gt;
&lt;p&gt;项目地址：&lt;a class=&#34;link&#34; href=&#34;https://github.com/CloakHQ/CloakBrowser&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/CloakHQ/CloakBrowser&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;截至写作时，GitHub API 显示这个仓库已有约 1.5 万 star，主要语言是 Python，许可证为 MIT。README 对它的定位很直接：一个可替代 Playwright / Puppeteer 启动器的 Stealth Chromium。&lt;/p&gt;
&lt;h2 id=&#34;它解决什么问题&#34;&gt;它解决什么问题
&lt;/h2&gt;&lt;p&gt;很多自动化脚本在普通 Headless Chromium 下会暴露明显自动化特征，例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;navigator.webdriver&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;Headless UA 泄漏。&lt;/li&gt;
&lt;li&gt;插件、字体、屏幕、GPU 等指纹不自然。&lt;/li&gt;
&lt;li&gt;CDP 行为和真实用户输入不一致。&lt;/li&gt;
&lt;li&gt;默认临时 profile 缺少正常浏览痕迹。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CloakBrowser 的思路是把一部分指纹修改放到 Chromium 源码层，而不是只在运行时做配置或 JS patch。这样对 Playwright 用户来说，使用方式仍然接近原来的浏览器自动化 API，但底层浏览器换成了项目提供的自定义构建。&lt;/p&gt;
&lt;p&gt;这类工具适合做合规的自动化测试、站点兼容性验证、反爬系统自测、Agent 浏览器环境实验。不要把它用于未授权访问、账号滥用、绕过平台风控或违反服务条款的场景。&lt;/p&gt;
&lt;h2 id=&#34;基本使用方式&#34;&gt;基本使用方式
&lt;/h2&gt;&lt;p&gt;Python 安装：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pip install cloakbrowser
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;JavaScript / Node.js 安装：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npm install cloakbrowser playwright-core
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;README 给出的 Python 示例很接近 Playwright：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;cloakbrowser&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;launch&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;browser&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;launch&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;page&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;browser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;new_page&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;page&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;goto&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https://protected-site.com&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;browser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;close&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;JavaScript 示例：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;launch&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;cloakbrowser&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;browser&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;launch&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;page&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;browser&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;newPage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;page&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;goto&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;https://protected-site.com&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;browser&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;close&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;第一次运行时，项目会自动下载对应平台的 Chromium 二进制文件，README 提到体积约 200MB，并会缓存到本地。&lt;/p&gt;
&lt;h2 id=&#34;browser-profile-manager&#34;&gt;Browser Profile Manager
&lt;/h2&gt;&lt;p&gt;CloakBrowser 还提供一个 Browser Profile Manager，可以自托管浏览器 profile，管理不同指纹、代理和持久会话。README 中的 Docker 启动方式如下：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker run -p 8080:8080 -v cloakprofiles:/data cloakhq/cloakbrowser-manager
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;启动后打开：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;http://localhost:8080
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这个方向更像开源的浏览器 profile 管理工具，适合需要多 profile、持久 cookie、隔离会话的自动化测试或内部 QA 场景。&lt;/p&gt;
&lt;h2 id=&#34;和普通-playwright-有什么差别&#34;&gt;和普通 Playwright 有什么差别
&lt;/h2&gt;&lt;p&gt;普通 Playwright 的优点是稳定、官方维护、API 成熟。CloakBrowser 的差别在于它使用自定义 Chromium，并提供一组源代码级别的指纹 patch。&lt;/p&gt;
&lt;p&gt;README 里列出的能力包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Canvas、WebGL、Audio、Fonts、GPU、Screen 等指纹处理。&lt;/li&gt;
&lt;li&gt;WebRTC IP spoofing。&lt;/li&gt;
&lt;li&gt;代理相关信号处理。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;humanize=True&lt;/code&gt; 模拟更自然的鼠标、键盘和滚动行为。&lt;/li&gt;
&lt;li&gt;Python 与 JavaScript 双端 API。&lt;/li&gt;
&lt;li&gt;Docker 镜像与 CDP server 模式。&lt;/li&gt;
&lt;li&gt;持久 profile。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;也就是说，它更适合对“浏览器环境真实性”有要求的自动化任务，而不是替代所有 Playwright 使用场景。&lt;/p&gt;
&lt;h2 id=&#34;使用时要注意什么&#34;&gt;使用时要注意什么
&lt;/h2&gt;&lt;p&gt;第一，浏览器自动化和反检测相关工具有很强的合规边界。它可以用于测试自己的站点、验证自动化环境、做内部 QA，也可以用于研究浏览器指纹；但不应被用于未经授权的抓取、账号批量注册、绕过访问控制、攻击或滥用服务。&lt;/p&gt;
&lt;p&gt;第二，README 中也说明，CloakBrowser 不内置代理轮换，也不是验证码解决服务。它提供浏览器层能力，网络信誉、账号信誉、行为策略和目标站点规则仍然会影响结果。&lt;/p&gt;
&lt;p&gt;第三，自定义 Chromium 二进制意味着供应链安全要额外关注。正式使用前建议检查版本、二进制来源、签名说明、许可证和更新机制。&lt;/p&gt;
&lt;h2 id=&#34;适合谁&#34;&gt;适合谁
&lt;/h2&gt;&lt;p&gt;适合三类用户：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;已经在用 Playwright / Puppeteer，但需要更接近真实浏览器环境的开发者。&lt;/li&gt;
&lt;li&gt;做浏览器自动化测试、兼容性测试或反爬策略验证的团队。&lt;/li&gt;
&lt;li&gt;需要给 AI Agent 提供浏览器执行环境的开发者。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果只是普通网页测试，原生 Playwright 已经够用。如果目标是研究浏览器指纹、profile 隔离和真实浏览器行为，CloakBrowser 值得关注。&lt;/p&gt;
&lt;h2 id=&#34;小结&#34;&gt;小结
&lt;/h2&gt;&lt;p&gt;CloakBrowser 的关键点不是“多写一个自动化封装”，而是把浏览器自动化的一部分伪装能力下沉到 Chromium 构建层。它保留了 Playwright / Puppeteer 的使用习惯，同时提供自定义浏览器、profile 管理、Docker 和 CDP server。&lt;/p&gt;
&lt;p&gt;这类工具能力强，也更需要谨慎使用。判断是否值得接入，重点看你的场景是否真的需要自定义 Chromium，而不是只因为普通 Headless 浏览器被某些检测服务标记。&lt;/p&gt;
&lt;p&gt;参考项目：&lt;a class=&#34;link&#34; href=&#34;https://github.com/CloakHQ/CloakBrowser&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/CloakHQ/CloakBrowser&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        
    </channel>
</rss>
