关于 exploring-browser
exploring-browser 是供 Claude Code 和其他 Agent 使用的浏览器探索与自动化技能。它将交互记录为 JSON 流程序列,供后续转换为 Robomotion SDK TypeScript,并设有只读探索规则。
主要功能
- 01交互式浏览器探索
- 02基于快照查找页面元素
- 03记录点击、输入和导航
- 04生成 JSON 流程序列
- 05捕获网络与控制台信息
- 06管理 Cookie 和会话
适用场景
- 01探索网站并梳理自动化流程
- 02通过快照定位交互元素
- 03检查网络流量以发现 API 端点
- 04利用捕获的控制台日志排查浏览器问题
MCP 相关
该技能使用 `robomotion-browser-mcp` 服务提供的浏览器工具进行导航、检查、交互和流程记录。MCP 用户在调用浏览器工具前,可能需要先加载延迟提供的工具架构。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ robomotionio/ agent-skills --skill exploring-browser安装后在 Claude Code 中输入/exploring-browser确认已加载。
附带文件config.jsondocs/patterns/browser.md
详细介绍
原文在翻译后有更新,译文可能不是最新。
浏览器探索技能
通过实时探索和流程录制实现交互式浏览器自动化。由 robomotion-browser-mcp 服务提供支持。
搭配使用: reversing-network — 捕获网络流量后,如果发现可用的 API,请从浏览器自动化切换到 HTTP。
概述
此技能支持你与 Claude 结对编程,共同探索网站、发现选择器并构建自动化流程。最后会生成一个JSON 流程序列,可直接映射到 Robomotion SDK TypeScript。
工作流
步骤 0 — 加载工具架构。 在 Claude Code 中,
mcp__browser__*工具会被延迟加载(目录中只有名称,需先获取其架构)。冷启动时调用browser_open会通过 stdio 发送空的/格式错误的 JSON,导致robomotion-browser-mcp崩溃,并在本次会话的剩余时间内将所有浏览器工具列入黑名单 — 此时,即使claude mcp list仍显示 ✓ Connected(这是一次新的探测,而非会话中已失效的管道),ToolSearch也会返回“no matching deferred tools”。首次调用前,请运行:ToolSearch query="select:mcp__browser__browser_open,mcp__browser__browser_navigate,mcp__browser__browser_snapshot,mcp__browser__browser_type,mcp__browser__browser_click,mcp__browser__browser_close,mcp__browser__browser_get_sequence,mcp__browser__browser_set_flow_name"(如果需要,可添加
browser_wait、browser_select、browser_query、browser_start_network_capture等。)服务失效后,只有重启 Claude Code 才能恢复 — 无法在会话内重新连接。使用其他运行时的 Agent 应替换为各自的 MCP 调用方式。
- 打开浏览器 - 使用
browser_open启动(默认启用隐身模式) - 导航 - 使用
browser_navigate前往目标 URL - 快照 - 使用
browser_snapshot查看包含 refs 的页面结构(主要探索工具) - 操作 - 使用快照中的 refs:
browser_click @e3、browser_type @e5(会自动记录 XPath) - 重新获取快照 - 页面发生变化后(点击、导航),获取新快照
- 关闭浏览器 - 探索完成后务必调用
browser_close— 这会返回流程序列 JSON 并释放浏览器 - 询问用户 - 展示计划/序列,并使用
AskUserQuestion询问是否继续构建流程 - 转换 - 仅在用户批准后,才将 JSON 转换为 robomotion-sdk 的 TypeScript 代码
重要: 完成所有步骤的探索后,必须关闭浏览器(browser_close)。编写/修改代码时,不要让浏览器保持打开状态。并且,在开始编写或修改流程代码之前,必须使用 AskUserQuestion 询问用户。
探索期间只读
探索时,网站是用户正在使用的实时系统。只读取,不要更改。
- 绝不要点击会更改数据的按钮:Merge、Approve、Deny、Delete、Remove、Pay、Send、Publish、Archive、Transfer、Confirm。统计这些按钮的数量,读取其标签及旁边的行,然后停在这里。
- 只有在点击对话框的取消按钮将其关闭,且不进行其他操作时,才可以打开对话框。如果一次点击既打开又提交,请勿点击。
- 更改操作应放在流程中:构建相应步骤,让机器人在用户运行流程时执行。这才是用户的要求 — 由机器人点击,而不是由你点击。
- 如果需要查看这类按钮被点击后的情况(确认页面、后续状态),请在点击前使用
AskUserQuestion询问用户,并明确说明这会更改他们的数据。如果脚本涉及此类操作,browser_eval会拒绝一次;如果browser_click的快照 ref 对应的元素名称是上述操作之一,也会拒绝。用户同意后,请再次调用,并设置confirmSideEffect: true。 - 如果意外更改了任何内容,请在同一轮回复中,先告知用户具体更改了什么。
核心概念
优先使用快照进行探索(强制)
每次遇到新 URL 或页面变化时,你的首个操作必须是 browser_snapshot。 这是不可协商的。快照约占用 50-100 个 token,而截图约占用 500-2000 个 token。
GOOD: browser_navigate → browser_snapshot → read tree → browser_click @e3
BAD: browser_navigate → browser_screenshot → browser_query → browser_query → ...
BAD: browser_navigate → browser_query → browser_query → browser_query → ...
规则:
- 每次导航后(
browser_navigate、会加载新页面的browser_click、browser_reload、browser_go_back),首次调用必须是browser_snapshot - 使用快照中的引用(
@e1、@e2……)作为操作工具中的选择器 - 执行会导致页面变化的操作(点击、提交表单)后,立即获取一张新快照
- 不要使用
browser_screenshot来探索页面——它会多消耗 10-40 倍 token。只有在无法仅凭快照引用继续操作时,才将截图作为最后手段(例如,遇到视觉布局问题、需要验证图像) - 不要使用
browser_query来探索页面——快照已显示所有交互元素。只对特定选择器进行有针对性的检查时才使用 query - 切勿连续多次调用
browser_query来“探索”页面——这正是快照的用途
引用 — 轻量级元素引用
快照会为交互元素分配 @e1、@e2 等引用。这些引用可用作所有操作工具中的选择器:
browser_click selector=@e3 → clicks the element, records its XPath
browser_type selector=@e5 text=hello → types into the element, records its XPath
引用是临时的——导航、刷新或返回页面时会失效。页面变化后,获取新快照以取得新的引用。
录制内容始终保存解析后的 XPath/CSS 选择器,而不是引用。这意味着 RPA 机器人会获得稳定的选择器。
探索模式
- explore=true(查询的默认值):不记录操作,仅用于探索
- explore=false(操作的默认值):将操作记录到流程序列中
| 工具类型 | 默认 explore 值 | 行为 |
|---|---|---|
快照(browser_snapshot) | — | 仅用于探索(永不记录) |
查询(browser_query、browser_get_text) | true | 用于探索,不记录 |
操作(browser_click、browser_type) | false | 记录到流程中 |
导航(browser_navigate) | false | 记录到流程中 |
| 截图 | true | 默认不记录 |
选择器
使用引用(优先)、XPath 或 CSS 选择器:
# Refs (from browser_snapshot) — PREFERRED
@e1, @e2, @e3
# XPath examples
//button[@id='submit']
//input[@name='email']
# CSS examples
#submit
input[name='email']
可用工具
生命周期
browser_open- 启动浏览器(传入headless: false以便用户查看;支持 stealth、视口选项)browser_close- 关闭浏览器并返回流程序列 JSON
导航
browser_navigate- 前往 URLbrowser_reload- 刷新页面browser_go_back- 返回上一页
探索
browser_snapshot- 始终优先使用——包含引用(@e1、@e2……)的无障碍树。每次导航后都必须使用。browser_screenshot- 仅作为最后手段——视觉截图。只有在无法继续操作,且快照引用不足以完成操作时才使用。browser_query- 有针对性地检查元素(谨慎使用——快照已显示所有内容)browser_get_text- 获取元素的文本内容browser_get_value- 获取输入框的值browser_get_attr- 获取属性值
操作(自动录制)
browser_click- 点击元素browser_type- 在输入框中输入browser_select- 选择下拉选项browser_wait- 等待元素browser_scroll- 滚动到元素browser_hover- 将鼠标悬停在元素上
上下文
browser_switch_iframe- 进入 iframebrowser_switch_main- 返回主页面
会话
browser_get_sequence- 获取当前 JSON 序列browser_clear_sequence- 开始新序列browser_set_flow_name- 设置流程名称
Cookies
browser_get_cookies- 获取 cookies(可按域名筛选)browser_set_cookie- 设置单个 cookiebrowser_set_cookies- 设置多个 cookiesbrowser_clear_cookies- 清除 cookies(可按域名筛选)
网络捕获(API 发现)
browser_start_network_capture- 开始捕获请求/响应browser_get_requests- 获取已捕获的请求(按方法/URL 筛选)browser_get_responses- 获取已捕获的响应(按状态码/URL 筛选)browser_get_request_response- 按 ID 获取请求-响应对browser_stop_network_capture- 停止捕获browser_clear_network_capture- 清除已捕获的数据
控制台捕获(调试)
browser_start_console_capture- 开始捕获控制台日志browser_get_console_logs- 获取已捕获的日志(按类型筛选)browser_clear_console_logs- 清除已捕获的日志browser_stop_console_capture- 停止捕获
会话持久化
browser_export_session- 将 Cookie、localStorage 和 URL 导出为 JSONbrowser_import_session- 导入之前导出的会话browser_save_session- 将会话保存到文件browser_load_session- 从文件加载会话
元素选择器(交互式选择)
browser_start_element_picker- 启动交互式元素选择器(悬停时以红色高亮)browser_get_picked_element- 获取用户通过 Ctrl+X 选中的元素browser_stop_element_picker- 停止选择器并移除高亮
示例会话
User: Automate login to example.com
Claude: I'll open a browser and explore the login page.
[browser_open stealth=true]
[browser_navigate url="https://example.com/login"]
[browser_snapshot]
// Returns:
// - textbox "Email" [ref=e1]
// - textbox "Password" [ref=e2] [type=password]
// - button "Sign In" [ref=e3]
Now I'll perform the login actions using refs:
[browser_type selector=@e1 text="[email protected]"]
[browser_type selector=@e2 text="secret123"]
[browser_click selector=@e3]
// Page changed — take a new snapshot to see what happened
[browser_snapshot]
// Done exploring — CLOSE THE BROWSER to get the flow sequence
[browser_close]
// Returns flow sequence JSON with resolved XPath selectors (not refs)
Claude: Here's the plan I recorded:
1. Open Browser → Navigate to login page
2. Type email → Type password → Click Sign In
[AskUserQuestion: "Should I build the TypeScript flow from this sequence?"]
// Only after user says yes:
Here's the TypeScript flow:
// ... generated code ...
提示
- 始终先获取快照 — 一次
browser_snapshot会显示所有带有 refs 的交互式元素。 - 页面变化后重新获取快照 — 导航/点击会使 refs 失效。
- 完成后关闭浏览器 — 始终调用
browser_close。编写代码时绝不要让浏览器保持打开状态。
将录制的 JSON 转换为 TypeScript 属于 creating-flow 的工作;此技能的任务到序列 JSON 为止。有关浏览器专用 SDK 模式(代理配置、选择器提示),请参阅 ./docs/patterns/browser.md。
结对编程工作流
找不到元素时——使用元素选择器!
多次尝试后仍找不到元素时,请使用交互式元素选择器,而不是让用户手动检查:
1. Take a screenshot to see current state
2. Try 2-3 different selector strategies
3. Check if element is in an iframe (browser_switch_iframe)
4. If still not found, START THE ELEMENT PICKER:
[browser_start_element_picker]
"I can't find the element. I've enabled the element picker -
please hover over the element you want and press Ctrl+X to select it.
Press Escape to cancel."
5. Wait for user, then retrieve the element:
[browser_get_picked_element]
6. Use the recommended selectors from the result
示例工作流:
Claude: I'm looking for the login button but can't find it with the usual selectors.
Let me enable the element picker so you can show me exactly which element you mean.
[browser_start_element_picker]
Result: Element picker started. User should hover over elements (red highlight)
and press Ctrl+X to select.
Claude: Please hover over the button you want me to click and press Ctrl+X.
You'll see a red highlight around elements as you hover.
--- User hovers and presses Ctrl+X ---
[browser_get_picked_element]
Result: {
"picked": true,
"element": {
"tagName": "button",
"className": "btn-primary submit-form",
"text": "Sign In",
"recommendedSelectors": [
{ "type": "xpath", "selector": "//button[contains(text(),'Sign In')]", "confidence": 80, "reason": "Contains text" },
{ "type": "xpath", "selector": "//button[@class='btn-primary submit-form']", "confidence": 70, "reason": "Class match" }
]
}
}
Claude: Got it! The button has text "Sign In". I'll use this selector:
[browser_click selector="//button[contains(text(),'Sign In')]"]
用于 API 发现的网络分析
使用网络捕获来了解页面使用了哪些 API:
1. browser_start_network_capture capture_body=true
2. Perform the action (login, form submit, etc.)
3. browser_get_requests method=POST
4. Analyze the API endpoints found
5. Suggest: "Instead of browser automation, you could use
Core.Net.HttpRequest directly with this endpoint"
示例工作流:
Claude: Let me capture network traffic to see what API this uses...
[browser_start_network_capture capture_body=true]
Claude: Now I'll fill in the login form...
[browser_type selector="//input[@name='email']" text="[email protected]"]
[browser_type selector="//input[@name='password']" text="password"]
[browser_click selector="//button[@type='submit']"]
Claude: Let me check what API calls were made...
[browser_get_requests method=POST]
Result: Found POST to /api/auth/login with JSON body:
{
"email": "[email protected]",
"password": "password"
}
Claude: I found the login API endpoint. Instead of browser automation,
you could create a simpler flow using Core.Net.HttpRequest:
- POST to /api/auth/login
- Store the auth token from response
- Use token for subsequent API calls
Would you prefer the API-based approach?
使用控制台日志调试
操作未按预期生效时:
1. browser_start_console_capture types=["error","warn"]
2. Retry the failing action
3. browser_get_console_logs type=error
4. Report findings and adjust approach
示例工作流:
Claude: The click didn't seem to work. Let me check for JavaScript errors...
[browser_start_console_capture types=["error","warn"]]
[browser_click selector="//button[@id='submit']"]
[browser_get_console_logs type=error]
Result: Error: "Cannot read property 'validate' of undefined" at form.js:42
Claude: Found a JavaScript error - the page has a bug in its validation code.
Let me try waiting for the form to fully load first...
[browser_wait selector="//form[@data-ready='true']"]
用于身份验证的会话持久化
处理需要身份验证的网站时:
1. Complete login manually or via automation
2. browser_export_session - save for later
3. Close browser, do other work
4. browser_open, browser_import_session - restore auth
示例工作流:
Claude: Let me save your authenticated session for later use...
[browser_export_session]
Session exported with 5 cookies and current URL.
Claude: I'll save this to a file so you can reuse it:
[browser_save_session path="/tmp/myapp-session.json"]
--- Later ---
Claude: Let me restore your previous session...
[browser_open]
[browser_load_session path="/tmp/myapp-session.json"]
Session restored - you're logged in as [email protected]
何时使用浏览器,何时使用 HTTP 请求
| 场景 | 建议 |
|---|---|
| 已知端点的简单 API | 使用 Core.Net.HttpRequest |
| 登录流程 → 需要身份验证 Cookie | 使用浏览器,然后导出会话 |
| 由复杂 JavaScript 渲染的内容 | 使用浏览器自动化 |
| 带有 CSRF 令牌的表单 | 使用浏览器(会自动处理令牌) |
| 抓取分页数据 | 从浏览器开始,如果找到 API 则切换到 API |
| 文件下载 | 使用浏览器进行身份验证,使用 API 下载 |
决策流程:
- 开始网络捕获
- 如果找到简洁的 REST API → 建议使用 HTTPRequest
- 如果身份验证/CSRF 复杂 → 继续使用浏览器
- 如果两者都需要 → 用浏览器进行身份验证,用 API 获取数据