关于 browser-harness
browser-harness 是通过 CDP 控制浏览器的技能,可连接用户正在运行的 Chrome 和现有会话。它为 Agent 提供交互式浏览、认证内容提取及视觉验证的操作指引。
主要功能
- 01通过 CDP 控制浏览器
- 02基于截图交互与检查
- 03提取需认证的页面内容
- 04使用远程浏览器会话
- 05复用交互操作指引
适用场景
- 01完成需登录的网站流程
- 02提取登录墙后的页面内容
- 03验证界面操作后的页面状态
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ davidondrej/ skills --skill browser-harness安装后在 Claude Code 中输入/browser-harness确认已加载。
附带文件references/install.md
详细介绍
browser-harness
通过 CDP 直接控制浏览器。针对特定任务的编辑,请使用 agent-workspace/agent_helpers.py。有关设置、安装或连接问题,请阅读 install.md。
**先检查路由:**如果任务不需要交互(无需点击、登录或填写表单),你只想获取页面内容,请改用 DeepAPI POST /v1/scrape/website,而不要驱动浏览器——请参阅 deepapi 技能。任务需要真实浏览器时,请使用 browser-harness:例如需要交互、处理依赖大量 JavaScript 的流程、使用已登录会话或进行视觉验证。
默认不启用域名技能(agent-workspace/domain-skills/ 下由社区贡献的各站点操作指南)。设置 BH_DOMAIN_SKILLS=1 即可启用;请参阅底部章节。
如果设置了 BH_DOMAIN_SKILLS=1,且任务针对特定网站,请先阅读匹配的 agent-workspace/domain-skills/<site>/ 目录中的每个文件,再设计操作方案。
用法
browser-harness -c '
new_tab("https://docs.browser-use.com")
wait_for_load()
print(page_info())
'
- 作为 browser-harness 调用——它已加入 $PATH。无需 cd,也无需 uv run。
- 首次导航应使用 new_tab(url),而不是 goto_url(url)——goto 会在用户当前活动标签页中运行,覆盖用户正在进行的操作。
工具调用格式
browser-harness -c '
# any python. helpers pre-imported. daemon auto-starts.
'
run.py 会在执行前调用 ensure_daemon()——除非你有意为之,否则无需手动启动或停止。
远程浏览器
可为并行子 Agent 使用远程浏览器(每个子 Agent 通过不同的 BU_NAME 获取独立浏览器),也可在无头服务器上使用。必须设置 BROWSER_USE_API_KEY。start_remote_daemon、list_cloud_profiles、list_local_profiles、sync_local_profile 均已预先导入。
监督这些子 Agent 时,每次检查后都要向用户发送一条非常简短的状态消息:说明它们正在做什么,以及进展是否顺利。
Claude Code cmux 提示:Claude 完成后,可能会预填一条预测的下一条用户消息;该草稿来自 Claude,并非用户发言。
browser-harness -c '
start_remote_daemon("work") # default — clean browser, no profile
# start_remote_daemon("work", profileName="my-work") # reuse a cloud profile (already logged in)
# start_remote_daemon("work", profileId="<uuid>") # same, but by UUID
# start_remote_daemon("work", proxyCountryCode="de", timeout=120) # DE proxy, 2-hour timeout
# start_remote_daemon("work", proxyCountryCode=None) # disable the Browser Use proxy
'
BU_NAME=work browser-harness -c '
new_tab("https://example.com")
print(page_info())
'
start_remote_daemon 会打印 liveUrl,并在检测到图形界面时自动在本地浏览器中打开,以便用户实时查看。无头服务器只会打印 URL——请将其分享给用户。守护进程会在关闭时向云端浏览器发送 PATCH 请求以停止运行,从而保留配置文件状态。远程守护进程运行期间会持续计费,直到超时。
配置文件(仅包含 Cookie 的登录状态)详见 interaction-skills/profile-sync.md——其中介绍了 list_cloud_profiles()、通过对话询问“使用哪个配置文件?”的模式,以及用于上传本地 Chrome 配置文件的 sync_local_profile()。
交互技能
如果你在导航时遇到某种具体操作机制的困难,请查看 interaction-skills/ 中的辅助工具。这些技能涵盖可复用的 UI 操作机制,例如对话框、标签页、下拉菜单、iframe 和上传。可用的交互技能包括:
- connection.md
- cookies.md
- cross-origin-iframes.md
- dialogs.md
- downloads.md
- drag-and-drop.md
- dropdowns.md
- iframes.md
- network-requests.md
- print-as-pdf.md
- profile-sync.md
- screenshots.md
- scrolling.md
- shadow-dom.md
- tabs.md
- uploads.md
- viewport.md
实际可行的方法
- 截图优先:使用 capture_screenshot() 快速了解当前页面、查找可见目标,并决定是否需要点击、使用选择器或继续导航。
- 点击:capture_screenshot() → 读取图像上的像素位置 → click_at_xy(x, y) → capture_screenshot() 进行验证。抑制「先定位,再点击」的 Playwright 习惯反射——不要使用 getBoundingClientRect,也不要搜寻选择器。仅当目标没有可见几何信息(隐藏输入框、0×0 节点)时才使用 DOM。命中测试在 Chrome 的浏览器进程中进行,因此点击可穿过 iframe / shadow DOM / 跨域内容,无需额外操作。
- 批量 HTTP 请求:使用 http_get(url) + ThreadPoolExecutor。静态页面无需浏览器(2.8 秒处理 249 个 Netflix 页面)。
- goto 后:使用 wait_for_load()。
- 标签页错误或过时:使用 ensure_real_tab()。当前标签页过时或属于内部页面时使用它;守护进程也会在下次调用时自动从过时会话中恢复。
- 验证:print(page_info()) 是最简单的「是否正常运行?」检查,但默认应通过截图验证可见操作是否确实生效。
- DOM 读取:当截图显示坐标并非合适工具时,使用 js(...) 进行检查和提取。
- iframe 网站(Azure blades、Salesforce):click_at_xy(x, y) 可以穿透;仅当坐标点击并非合适工具时,才使用 iframe DOM 操作。
- 身份验证墙:被重定向到登录页面时,停止操作并询问用户。不要根据截图输入凭据。
- 对于辅助函数未覆盖的操作:使用原始 CDP 调用 cdp("Domain.method", params)。
设计约束
- 默认使用坐标点击。Input.dispatchMouseEvent 在合成器层级穿过 iframe / shadow DOM / 跨域内容。
- 连接到用户正在运行的 Chrome。不要启动自己的浏览器。
- cdp-use 仅用于 CDPClient.send_raw。优先使用原始 CDP 字符串,而非类型化封装。
- run.py 保持精简。不要添加 argparse、子命令或额外的控制层。
- 核心辅助函数保持简短。针对特定任务新增的辅助函数放在
agent-workspace/agent_helpers.py中;守护进程/引导程序和远程会话管理放在核心包中。 - 不要添加管理层。不要添加重试框架、会话管理器、守护进程监督程序、配置系统或日志框架。
Hermes Agent 集成
以可编辑模式安装在 ~/Developer/browser-harness:uv tool install -e .。二进制文件位于 ~/.local/bin/browser-harness。技能位于 ~/.hermes/skills/browser-harness/。
Frontmatter 注意事项: 上游 SKILL.md 的 frontmatter 中包含 name: browser,这会与 Hermes 内置的 browser 工具集冲突。复制到 ~/.hermes/skills/ 时,请将 frontmatter 中的名称改为 name: browser-harness,否则 Hermes 会遮蔽自身的浏览器工具,或与其冲突。
Brave Browser: 与 Chrome 的工作方式完全相同。在 brave://inspect/#remote-debugging 中启用远程调试(勾选同一个复选框)。该工具会自动发现 Brave 的配置目录。
已验证的经过身份验证的内容提取模式
browser-harness 会连接到用户实际使用且已登录的浏览器,非常适合从登录墙后的网站提取内容;在这些网站上,web_extract 或 Hermes 内置的 browser_navigate 会失效(例如 X/Twitter 文章、LinkedIn 和付费墙网站)。
模式:
browser-harness -c '
new_tab("https://x.com/user/status/123456")
wait_for_load()
import time
time.sleep(5) # let JS-heavy pages render
text = js("""
const article = document.querySelector("article");
if (article) return article.innerText;
return document.body.innerText;
""")
with open("/tmp/extracted.txt", "w") as f:
f.write(text)
print("Written", len(text), "chars")
'
- 写入临时文件,避免大型文本的 Shell 转义问题
- 对 JavaScript 密集型单页应用(SPA)适当使用
time.sleep()等待(X 和 LinkedIn 需要 3-5 秒) - X/Twitter 文章会以内嵌方式呈现——只需通过 DOM 滚动/提取内容,无需额外点击
- 对于很长的页面,使用带
innerText的js(...)可抓取全部内容,包括首屏以下的内容
Hermes Agent 集成
以可编辑模式安装在 ~/Developer/browser-harness:uv tool install -e .。二进制文件位于 ~/.local/bin/browser-harness。技能位于 ~/.hermes/skills/browser-harness/。
**Frontmatter 注意事项:**上游的 SKILL.md 在 frontmatter 中使用 name: browser,这会与 Hermes 内置的 browser 工具集冲突。复制到 ~/.hermes/skills/ 时,请将 frontmatter 中的名称改为 name: browser-harness。
**Brave Browser:**使用方式与 Chrome 完全相同。在 brave://inspect/#remote-debugging 中启用远程调试(使用相同的复选框)。该工具会自动发现 Brave 的配置文件目录。
已验证的身份验证内容提取模式
browser-harness 会连接到用户正在使用且会话已激活的真实浏览器,非常适合处理需要登录的网站;在这类网站上,web_extract 或 Hermes 内置的 browser_navigate 会失败(如 X/Twitter 文章、LinkedIn、付费墙网站)。
browser-harness -c '
new_tab("https://x.com/user/status/123456")
wait_for_load()
import time
time.sleep(5) # let JS-heavy pages render
text = js("""
const article = document.querySelector("article");
if (article) return article.innerText;
return document.body.innerText;
""")
with open("/tmp/extracted.txt", "w") as f:
f.write(text)
print("Written", len(text), "chars")
'
- 写入临时文件,以避免处理大段文本时的 shell 转义问题
- 对 JavaScript 密集型单页应用使用
time.sleep()并留出充足时间(X、LinkedIn 需要 3-5s) - X/Twitter 文章会内嵌渲染,只需通过 DOM 滚动或提取内容,无需额外点击
- 使用带有
innerText的js(...)可抓取所有内容,包括首屏以下的内容
注意事项(实测)
- Brave Browser 使用
brave://inspect/#remote-debugging,而不是chrome://inspect/...。该工具会自动发现 Brave 的数据目录。 - 提取需要登录才能访问的内容(如 X/Twitter 文章)时:使用
new_tab(url)导航,调用wait_for_load(),然后通过js("document.querySelector('article').innerText")提取。写入临时文件可避免 shell 转义:with open('/tmp/out.txt', 'w') as f: f.write(text)。用户现有的浏览器会话会自动处理身份验证。 - Omnibox 弹出窗口是假页面目标。需要真实标签页时,请过滤
chrome://omnibox-popup...及其他内部页面。 - CDP 目标顺序与 Chrome 可见的标签栏顺序不一致。如果用户指的是“我能看到的第一个/第二个标签页”,请使用 UI 自动化;
Target.activateTarget只能显示已知目标。 - 默认守护进程会话可能会失效。
ensure_real_tab()会重新连接到真实页面。 - Browser Use API 在线路上使用 camelCase。
cdpUrl、proxyCountryCode等均如此。 - 远程
cdpUrl使用 HTTPS,而不是 ws。通过/json/version获取 WebSocket URL。 - 使用 PATCH /browsers/{id} + {"action":"stop"} 停止云浏览器。
- 每次执行有意义的操作后,都应重新截图,再判断操作是否成功。通过图像检查状态变化、打开的菜单、页面导航、可见错误,以及页面是否处于预期状态。
- 使用截图来探索页面。这通常是找到下一个点击目标、发现隐藏阻碍,以及判断是否值得编写选择器的最快方式。
- 优先使用合成器级操作,而不是框架技巧。先尝试截图、坐标点击和原始按键输入,再添加特定于 DOM 的变通方法。
- 如果需要特定于框架的 DOM 技巧,请先查看 interaction-skills/。下拉菜单、对话框、iframe、Shadow DOM 和表单相关指南都应放在那里。
领域技能(选择启用)
仅在 BH_DOMAIN_SKILLS=1 时生效。否则请忽略——agent-workspace/domain-skills/ 处于休眠状态,goto_url 不会显示技能文件。
启用后,在自行设计方法之前,先搜索 agent-workspace/domain-skills/<host>/。goto_url 会返回已导航主机对应的最多 10 个技能文件名。
如果发现任何不显而易见的信息——如私有 API、稳定选择器、框架特性、URL 模式、隐藏的等待条件或特定于网站的陷阱——请向 agent-workspace/domain-skills/<site>/ 提交 PR。记录网站的持久性结构(地图,而不是日记)。不要写入像素坐标(布局变化会导致失效)、任务叙述或机密信息——该目录是公开的。