第 17 章:浏览器自动化与网页交互
难度: ⭐⭐⭐⭐ 高级 预计阅读: 22 分钟 前置章节: 第 6 章
浏览器自动化是 AI Agent 与真实互联网世界交互的桥梁。本章深入讲解 OpenClaw 的 Browser Relay 架构,涵盖配置启动、网页浏览、信息抓取、表单自动化、截图分析以及合规使用指南。掌握浏览器自动化后,你的 Agent 将具备”上网”能力——自主搜索信息、填写表单、监控页面变化。
📑 本章目录
- 17.1 Browser Relay 架构
- 17.2 Browser Relay 配置与启动
- 17.3 网页浏览与信息抓取
- 17.4 表单填写与自动化操作
- 17.6 反爬策略与合规使用
- 17.7 与 Skill 结合:浏览器驱动的自动化任务
- 实操练习
- 常见问题 (FAQ)
- 本章小结
17.1 Browser Relay 架构
17.1.1 整体架构图
OpenClaw 的浏览器自动化采用 Agent → Relay → Browser 三层架构,将浏览器操作与 Agent 推理解耦:
┌───────────────────────────────────────────────────────────────────────┐
│ OpenClaw Agent │
│ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ 推理引擎 │ │
│ │ │ │
│ │ "用户要我查一下携程上北京到上海的高铁票价" │ │
│ │ → 决策:需要浏览网页 │ │
│ │ → 调用 browser_navigate("https://www.ctrip.com") │ │
│ │ → 调用 browser_extract_text() │ │
│ │ → 解析结果,返回给用户 │ │
│ └────────────────────────────┬─────────────────────────────────┘ │
│ │ 工具调用 │
└───────────────────────────────┼───────────────────────────────────────┘
│
HTTP/WebSocket 通信
│
┌───────────────────────────────┼───────────────────────────────────────┐
│ Browser Relay (中继服务) │
│ │ │
│ ┌────────────────────────────▼──────────────────────────────────┐ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────────┐ │ │
│ │ │ 请求队列 │ │ 速率限制 │ │ 页面缓存 │ │ Cookie 管理 │ │ │
│ │ │ Queue │→ │ Limiter │→ │ Cache │ │ Cookies │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ └────────────┘ │ │
│ └────────────────────────────┬──────────────────────────────────┘ │
│ │ │
│ CDP (Chrome DevTools Protocol) │
│ │ │
│ ┌────────────────────────────▼──────────────────────────────────┐ │
│ │ Chromium / Chrome 浏览器实例 │ │
│ │ │ │
│ │ ┌──────┐ ┌──────┐ ┌──────┐ │ │
│ │ │ Tab 1│ │ Tab 2│ │ Tab 3│ ... │ │
│ │ └──────┘ └──────┘ └──────┘ │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ │
│ ~/.openclaw/browser-relay/ │
└───────────────────────────────────────────────────────────────────────┘
17.1.2 核心组件说明
| 组件 | 职责 | 存储位置 |
|---|---|---|
| Agent 推理引擎 | 决定何时以及如何使用浏览器,解析返回结果 | Agent 进程中 |
| Browser Relay | 中继服务,管理浏览器实例、请求队列、速率控制 | ~/.openclaw/browser-relay/ |
| 浏览器实例 | 实际执行页面渲染、JS 执行、网络请求 | 系统 Chromium 进程 |
| User Data | 浏览器用户数据(Cookie、缓存、登录态) | ~/.openclaw/browser/openclaw/user-data/ |
17.1.3 通信流程
一次完整的网页交互流程如下:
1. Agent 推理 → 识别需要浏览器操作
2. Agent → Relay:发送浏览器操作指令(HTTP POST)
↓
3. Relay 入队:加入请求队列,应用速率限制
↓
4. Relay → Browser:通过 CDP 控制 Chromium 执行操作
↓
5. Browser 执行:导航到页面 / 点击元素 / 提取内容
↓
6. Browser → Relay:返回执行结果(HTML / 文本 / 截图)
↓
7. Relay → Agent:返回处理后的结果
↓
8. Agent 推理 → 解析网页内容,继续下一步操作或回复用户
17.1.4 与 Puppeteer MCP 的区别
| 维度 | Browser Relay(OpenClaw 内置) | Puppeteer MCP Server |
|---|---|---|
| 集成方式 | 内置工具,开箱即用 | 需配置 MCP Server |
| 浏览器管理 | Relay 统一管理生命周期 | 每次调用可能新建实例 |
| 会话保持 | ✅ 持久化 Cookie 和登录态 | 需手动管理 |
| 速率控制 | ✅ 内置限流和队列 | 需自行实现 |
| 页面缓存 | ✅ 智能缓存减少重复访问 | 无 |
| 截图分析 | ✅ 结合 Vision 模型 | 仅返回截图文件 |
| 适用场景 | 日常网页交互、信息采集 | 复杂 DOM 操作、端到端测试 |
[!TIP] 对于大多数网页交互场景,使用 OpenClaw 内置的 Browser Relay 即可。Puppeteer MCP 更适合需要精细 DOM 操作的高级场景。
17.2 Browser Relay 配置与启动
17.2.1 目录结构
Browser Relay 的文件布局如下:
~/.openclaw/
├── browser-relay/ # Relay 服务目录
│ ├── config.json # Relay 配置文件
│ ├── relay.pid # 进程 PID 文件
│ └── logs/ # Relay 日志
│ ├── relay.log # 主日志
│ └── network.log # 网络请求日志
├── browser/
│ └── openclaw/
│ └── user-data/ # 浏览器用户数据
│ ├── Default/ # 默认 Profile
│ ├── Cookies # Cookie 存储
│ ├── Local Storage/ # 本地存储
│ └── Cache/ # 页面缓存
└── media/
└── inbound/ # 截图和下载文件
├── screenshot-*.png
└── download-*/
17.2.2 配置选项
编辑 ~/.openclaw/browser-relay/config.json:
{
"browser": {
"executablePath": "/usr/bin/chromium-browser",
"headless": true,
"args": [
"--no-sandbox",
"--disable-gpu",
"--disable-dev-shm-usage",
"--window-size=1920,1080"
],
"userDataDir": "~/.openclaw/browser/openclaw/user-data",
"defaultViewport": {
"width": 1920,
"height": 1080,
"deviceScaleFactor": 1
}
},
"relay": {
"port": 18790,
"maxConcurrentPages": 5,
"pageTimeout": 30000,
"navigationTimeout": 15000,
"requestQueueSize": 50
},
"rateLimit": {
"enabled": true,
"maxRequestsPerMinute": 30,
"minDelayBetweenRequests": 2000,
"respectRobotsTxt": true
},
"cache": {
"enabled": true,
"maxSize": "500MB",
"ttl": 3600,
"excludePatterns": [
"*.api.*",
"*/login*",
"*/checkout*"
]
},
"screenshots": {
"outputDir": "~/.openclaw/media/inbound",
"format": "png",
"quality": 85,
"fullPage": false
}
}
核心配置说明:
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
browser.headless |
boolean | true |
无头模式运行浏览器 |
browser.args |
string[] | - | Chromium 启动参数 |
relay.maxConcurrentPages |
number | 5 |
最大同时打开页面数 |
relay.pageTimeout |
number | 30000 |
页面操作超时(毫秒) |
rateLimit.maxRequestsPerMinute |
number | 30 |
每分钟最大请求数 |
rateLimit.minDelayBetweenRequests |
number | 2000 |
两次请求最小间隔(毫秒) |
rateLimit.respectRobotsTxt |
boolean | true |
是否遵守 robots.txt |
cache.ttl |
number | 3600 |
缓存有效期(秒) |
17.2.3 启动与验证
# 启动 Browser Relay 服务
openclaw browser start
# 输出示例:
# ✅ Browser Relay 已启动
# 端口: 18790
# 浏览器: Chromium 120.0.6099.71 (headless)
# 最大并发页面: 5
# 速率限制: 30 req/min
# 查看 Relay 状态
openclaw browser status
# 输出示例:
# Browser Relay Status:
# PID: 12345
# Uptime: 2h 15m
# Active Pages: 2/5
# Total Requests: 147
# Cache Hit Rate: 62%
# Queue Length: 0
# 停止 Browser Relay
openclaw browser stop
# 重启(重新加载配置)
openclaw browser restart
[!NOTE] 在服务器环境(无图形界面)中,必须使用
headless: true模式。如果需要调试,可以通过远程桌面或 VNC 连接后设置headless: false观察浏览器实际行为。
17.2.4 浏览器 Profile 管理
Browser Relay 使用持久化的浏览器 Profile,这意味着:
- Cookie 持久化:登录某个网站后,下次访问自动保持登录状态
- LocalStorage 保留:网站的本地存储数据在重启后仍然可用
- 历史记录积累:浏览器会积累访问历史(可定期清理)
# 查看 Profile 占用空间
du -sh ~/.openclaw/browser/openclaw/user-data/
# 清理缓存(保留 Cookie 和登录态)
openclaw browser clear-cache
# 完全重置 Profile(清除所有数据,包括登录态)
openclaw browser reset-profile
# 导出 Profile(备份)
tar -czf browser-profile-backup.tar.gz \
~/.openclaw/browser/openclaw/user-data/
[!WARNING] 执行
reset-profile会清除所有网站的登录状态。如果你在浏览器中登录了重要服务(如 GitHub、企业内部系统),请先做好备份。
17.3 网页浏览与信息抓取
17.3.1 基本页面访问
Agent 可以通过内置的浏览器工具访问网页:
用户:帮我看看 Hacker News 今天的热门文章。
Agent(内部推理):
→ 调用 browser_navigate
→ URL: "https://news.ycombinator.com"
→ 等待页面加载完成
→ 调用 browser_extract_text
→ 提取模式: "main_content"
→ 返回页面文本内容
对应的工具调用:
// 步骤 1:导航到目标页面
await browser_navigate({
url: "https://news.ycombinator.com",
waitUntil: "networkidle", // 等待网络空闲
timeout: 15000, // 15 秒超时
});
// 步骤 2:提取页面内容
const content = await browser_extract_text({
extractMode: "text", // 纯文本模式
maxChars: 8000, // 限制返回字符数
selector: ".titleline", // 可选:仅提取匹配选择器的内容
});
17.3.2 内容提取模式
Browser Relay 支持多种内容提取模式:
| 模式 | 说明 | 适用场景 |
|---|---|---|
text |
提取纯文本,去除 HTML 标签 | 文章、新闻页面 |
html |
返回原始 HTML | 需要保留页面结构 |
markdown |
将 HTML 转换为 Markdown | 保留格式的内容提取 |
structured |
尝试提取结构化数据(JSON-LD、表格等) | 电商、数据表页面 |
screenshot |
截图并返回图片 | 复杂布局、图表页面 |
// 纯文本提取
const text = await browser_extract_text({
extractMode: "text",
maxChars: 5000,
});
// Markdown 提取(保留标题、链接、列表等格式)
const markdown = await browser_extract_text({
extractMode: "markdown",
maxChars: 10000,
});
// 结构化提取(如提取表格数据)
const structured = await browser_extract_text({
extractMode: "structured",
selector: "table.price-table",
});
17.3.3 结构化数据抓取
对于表格、列表等结构化内容,可以使用 CSS 选择器精准提取:
// 提取电商搜索结果
const products = await browser_evaluate({
script: `
const items = document.querySelectorAll('.product-card');
return Array.from(items).map(item => ({
name: item.querySelector('.title')?.textContent?.trim(),
price: item.querySelector('.price')?.textContent?.trim(),
rating: item.querySelector('.rating')?.textContent?.trim(),
link: item.querySelector('a')?.href,
}));
`,
});
Agent 对话示例:
用户:搜索一下京东上 "机械键盘" 的前 5 个结果和价格。
Agent(执行流程):
1. browser_navigate → "https://search.jd.com/Search?keyword=机械键盘"
2. browser_wait_for_selector → ".gl-item"(等待商品列表加载)
3. browser_evaluate → 提取商品名称、价格、链接
4. 整理结果返回给用户
Agent 回复:
以下是京东搜索"机械键盘"的前 5 个结果:
| # | 商品名称 | 价格 |
|---|---------|------|
| 1 | CHERRY MX-BOARD 2.0S | ¥399 |
| 2 | 罗技 K845 机械键盘 | ¥349 |
| 3 | IKBC C87 机械键盘 | ¥298 |
| 4 | 达尔优 A87 机械键盘 | ¥189 |
| 5 | 雷蛇 BlackWidow V4 | ¥899 |
17.3.4 多页面导航
Browser Relay 支持同时管理多个标签页:
// 打开新标签页
const page1 = await browser_new_page({ url: "https://example.com/page1" });
const page2 = await browser_new_page({ url: "https://example.com/page2" });
// 切换标签页
await browser_switch_page({ pageId: page1.id });
// 获取当前所有标签页信息
const pages = await browser_list_pages();
// 返回: [{ id: "page-1", url: "...", title: "..." }, ...]
// 关闭指定标签页
await browser_close_page({ pageId: page2.id });
17.4 表单填写与自动化操作
17.4.1 元素定位与交互
Browser Relay 支持多种元素定位方式:
// CSS 选择器定位
await browser_click({ selector: "#submit-btn" });
// XPath 定位
await browser_click({ xpath: "//button[contains(text(), '提交')]" });
// 文本内容定位
await browser_click({ text: "登录" });
// 等待元素出现后再操作
await browser_wait_for_selector({
selector: ".result-list",
timeout: 10000,
visible: true,
});
元素定位优先级建议:
| 方式 | 稳定性 | 可读性 | 推荐度 |
|---|---|---|---|
id 选择器 |
⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | 首选 |
data-testid 属性 |
⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | 首选 |
| CSS class 选择器 | ⭐⭐⭐ | ⭐⭐⭐ | 备选 |
| XPath | ⭐⭐ | ⭐⭐ | 仅在无其他选择时 |
| 文本内容 | ⭐⭐ | ⭐⭐⭐⭐⭐ | 简单场景 |
17.4.2 表单填写流程
一个完整的表单填写示例:
// 1. 导航到表单页面
await browser_navigate({
url: "https://example.com/register",
waitUntil: "domcontentloaded",
});
// 2. 填写文本输入框
await browser_fill({
selector: "input[name='username']",
value: "openclaw_user",
});
await browser_fill({
selector: "input[name='email']",
value: "user@example.com",
});
await browser_fill({
selector: "input[name='password']",
value: "SecurePass123!",
});
// 3. 选择下拉框
await browser_select({
selector: "select[name='country']",
value: "CN",
});
// 4. 勾选复选框
await browser_check({
selector: "input[name='agree_terms']",
checked: true,
});
// 5. 选择单选按钮
await browser_click({
selector: "input[name='gender'][value='other']",
});
// 6. 提交表单
await browser_click({
selector: "button[type='submit']",
});
// 7. 等待提交结果
await browser_wait_for_navigation({
timeout: 10000,
});
// 8. 验证结果
const resultText = await browser_extract_text({
selector: ".success-message",
});
Agent 对话示例:
用户:帮我在 XX 平台注册一个测试账号,用户名 test_0306,邮箱 test@demo.com。
Agent(执行流程):
1. 导航到注册页面
2. 截图确认页面结构
3. 填写用户名、邮箱、生成安全密码
4. 勾选用户协议
5. 提交表单
6. 截图确认注册成功
7. 将账号信息保存到 memory
Agent 回复:注册完成!账号信息:
- 用户名:test_0306
- 邮箱:test@demo.com
- 密码已保存到记忆中
17.4.3 按钮点击与导航
// 基本点击
await browser_click({ selector: ".action-btn" });
// 双击
await browser_dblclick({ selector: ".edit-zone" });
// 右键点击
await browser_click({ selector: ".context-item", button: "right" });
// 鼠标悬停(触发下拉菜单等)
await browser_hover({ selector: ".dropdown-trigger" });
// 键盘输入
await browser_type({ text: "搜索关键词" });
await browser_press({ key: "Enter" });
// 组合键
await browser_press({ key: "Control+A" }); // 全选
await browser_press({ key: "Control+C" }); // 复制
// 滚动页面
await browser_scroll({
direction: "down",
distance: 500, // 像素
});
// 滚动到指定元素
await browser_scroll_to_element({
selector: "#footer",
});
17.4.4 文件上传与下载
// 文件上传
await browser_upload_file({
selector: "input[type='file']",
filePath: "/tmp/document.pdf",
});
// 触发下载并等待完成
const downloadInfo = await browser_download({
selector: "a.download-link",
outputDir: "~/.openclaw/media/inbound/downloads",
timeout: 60000,
});
// 返回: { filePath: "~/.openclaw/media/inbound/downloads/report.xlsx", size: 102400 }
// Agent 可以进一步处理下载的文件
17.5 截图与页面分析
17.5.1 全页截图
截图是浏览器自动化的重要能力,尤其在需要视觉分析时:
// 当前视窗截图
const screenshot = await browser_screenshot({
fullPage: false,
format: "png",
});
// 返回: { filePath: "~/.openclaw/media/inbound/screenshot-20260306-102345.png" }
// 全页截图(包括滚动区域)
const fullScreenshot = await browser_screenshot({
fullPage: true,
format: "png",
quality: 90,
});
17.5.2 区域截图
// 截取特定元素
const elementShot = await browser_screenshot({
selector: ".chart-container",
format: "png",
});
// 截取指定区域(坐标)
const areaShot = await browser_screenshot({
clip: {
x: 100,
y: 200,
width: 800,
height: 600,
},
format: "png",
});
17.5.3 视觉分析与理解
当页面内容难以用文字提取时(如图表、可视化、复杂排版),Agent 可以结合截图与 Vision 模型进行分析:
Agent(内部推理):
1. 页面包含复杂图表,纯文本提取效果不佳
2. 调用 browser_screenshot 截取图表区域
3. 将截图传递给 Vision 模型进行分析
4. 得到图表的数据解读
实际对话示例:
用户:帮我看看 A 股今天的大盘走势图。
Agent(执行流程):
1. browser_navigate → 东方财富网大盘页面
2. browser_wait_for_selector → ".chart-area"
3. browser_screenshot → 截取走势图
4. 分析截图内容(Vision 模型)
Agent 回复:今天大盘走势概述:
- 开盘:3,285.42 点
- 最高:3,312.18 点(10:30 左右)
- 最低:3,271.55 点(14:00 左右)
- 收盘:3,298.67 点
- 从走势图看,早盘冲高后震荡回落,午后小幅反弹...
17.5.4 页面变化监控
结合 Cron 定时任务和截图对比,可以实现页面变化监控:
# 页面监控 Skill 核心逻辑(伪代码)
#!/bin/bash
# monitor-page.sh
URL="https://example.com/status"
CURRENT=$(openclaw browser screenshot --url "$URL" --output /tmp/current.png)
PREVIOUS="/tmp/previous.png"
if [ -f "$PREVIOUS" ]; then
# 比较两张截图的差异
DIFF=$(compare -metric RMSE "$PREVIOUS" "$CURRENT" /tmp/diff.png 2>&1)
if (( $(echo "$DIFF > 100" | bc -l) )); then
echo "⚠️ 页面发生显著变化!差异值:$DIFF"
# 触发通知
openclaw notify "页面变化检测:$URL 已更新"
fi
fi
cp "$CURRENT" "$PREVIOUS"
17.6 反爬策略与合规使用
17.6.1 法律与伦理边界
[!WARNING] 使用浏览器自动化时,必须遵守相关法律法规和网站使用条款。以下是必须遵循的原则:
必须遵守:
- ✅ 遵守目标网站的
robots.txt规则 - ✅ 遵守网站的使用条款和服务协议
- ✅ 控制访问频率,不对目标网站造成负担
- ✅ 仅抓取公开可访问的信息
- ✅ 正确处理个人隐私数据(GDPR、个人信息保护法等)
绝对禁止:
- ❌ 绕过付费墙获取付费内容
- ❌ 抓取需要破解验证码才能访问的内容
- ❌ 大规模抓取并转售他人数据
- ❌ 冒充真实用户进行欺诈操作
- ❌ 干扰或破坏目标网站的正常运行
17.6.2 robots.txt 遵守
Browser Relay 默认启用 respectRobotsTxt:
{
"rateLimit": {
"respectRobotsTxt": true
}
}
当此选项启用时,Relay 会在首次访问某域名时自动请求 robots.txt,并缓存规则:
Agent 请求访问 → https://example.com/admin/stats
Relay 检查 robots.txt:
User-agent: *
Disallow: /admin/
Relay 响应:
❌ 该路径被 robots.txt 禁止访问
→ Agent 收到错误信息并放弃访问
# 手动检查某个 URL 是否被 robots.txt 允许
openclaw browser check-robots "https://example.com/some-page"
# 输出:
# ✅ https://example.com/some-page — 允许访问
# ❌ https://example.com/admin/ — robots.txt 禁止
17.6.3 速率限制配置
合理的速率限制是合规使用的关键:
{
"rateLimit": {
"enabled": true,
"maxRequestsPerMinute": 30,
"minDelayBetweenRequests": 2000,
"perDomainLimits": {
"github.com": {
"maxRequestsPerMinute": 20,
"minDelayBetweenRequests": 3000
},
"*.gov.cn": {
"maxRequestsPerMinute": 10,
"minDelayBetweenRequests": 6000
}
}
}
}
推荐速率设置:
| 目标类型 | 建议 RPM | 建议间隔 | 说明 |
|---|---|---|---|
| 公开信息站点 | ≤ 30 | ≥ 2s | 新闻、博客、文档 |
| 电商平台 | ≤ 15 | ≥ 4s | 价格查询、商品信息 |
| 社交平台 | ≤ 10 | ≥ 6s | 通常有严格反爬 |
| 政府网站 | ≤ 10 | ≥ 6s | 保持低频访问 |
| API 性质的页面 | ≤ 60 | ≥ 1s | 如 JSON 接口 |
[!TIP] 如果你不确定合适的速率,从保守值开始(10 RPM / 6s 间隔),然后根据实际情况逐步调整。观察是否触发 429(Too Many Requests)或验证码。
17.6.4 反检测措施说明
Browser Relay 默认使用真实的 Chromium 浏览器,自带以下特征:
- 标准的 User-Agent 字符串(与真实 Chrome 一致)
- 完整的浏览器指纹(Canvas、WebGL、字体等)
- 正常的 JavaScript 执行环境
- Cookie 和 Session 管理
[!NOTE] OpenClaw 的浏览器自动化不以”绕过反爬”为目标。如果某个网站明确阻止自动化访问,应该尊重网站方的决定,转而使用其官方 API 或联系网站获取数据授权。
17.7 与 Skill 结合:浏览器驱动的自动化任务
17.7.1 Skill 中使用浏览器工具
将浏览器操作封装为 Skill,可以实现可复用的网页自动化流程。Skill 配置中声明对浏览器能力的依赖:
# skills/web-price-monitor/skill.yaml
name: web-price-monitor
version: 1.0.0
description: 监控目标商品价格变化并通知
triggers:
- keyword: "监控价格"
- cron: "0 9,18 * * *" # 每天 9:00 和 18:00 执行
capabilities:
- browser # 声明需要浏览器能力
- notification # 声明需要通知能力
parameters:
- name: product_url
type: string
description: 商品页面 URL
- name: target_price
type: number
description: 目标价格(低于此价格时通知)
17.7.2 实例:竞品价格监控 Skill
一个完整的价格监控 Skill 实现:
#!/bin/bash
# skills/web-price-monitor/run.sh
# 竞品价格监控 - 浏览器自动化 Skill
PRODUCT_URL="${1:-https://item.jd.com/100012345.html}"
TARGET_PRICE="${2:-500}"
MEMORY_DIR="$HOME/.openclaw/workspace/memory"
PRICE_LOG="$MEMORY_DIR/price-monitor-log.md"
echo "🔍 开始价格监控: $PRODUCT_URL"
echo "📌 目标价格: ¥$TARGET_PRICE"
# 1. 浏览器导航到商品页面
PRICE_DATA=$(openclaw browser evaluate \
--url "$PRODUCT_URL" \
--script '
const name = document.querySelector(".sku-name")?.textContent?.trim();
const price = document.querySelector(".price .p-price span:last-child")?.textContent?.trim();
const shop = document.querySelector(".shop-name")?.textContent?.trim();
return JSON.stringify({ name, price, shop });
' \
--wait-for ".p-price" \
--timeout 15000)
# 2. 解析价格数据
CURRENT_PRICE=$(echo "$PRICE_DATA" | jq -r '.price')
PRODUCT_NAME=$(echo "$PRICE_DATA" | jq -r '.name')
echo "📦 商品:$PRODUCT_NAME"
echo "💰 当前价格:¥$CURRENT_PRICE"
# 3. 记录价格到 memory
DATE=$(date +%Y-%m-%d)
TIME=$(date +%H:%M)
echo "| $DATE $TIME | ¥$CURRENT_PRICE | $PRODUCT_NAME |" >> "$PRICE_LOG"
# 4. 价格达标时发送通知
if (( $(echo "$CURRENT_PRICE <= $TARGET_PRICE" | bc -l) )); then
echo "🎉 价格已降至目标价格!发送通知..."
openclaw notify "💰 价格提醒:$PRODUCT_NAME 当前价格 ¥$CURRENT_PRICE,已低于目标价 ¥$TARGET_PRICE!"
fi
# 5. 截图存档
openclaw browser screenshot \
--url "$PRODUCT_URL" \
--selector ".product-intro" \
--output "$HOME/.openclaw/media/inbound/price-$(date +%Y%m%d%H%M).png"
echo "✅ 监控完成"
17.7.3 实例:自动化招聘信息采集
将浏览器自动化与 Memory 系统结合,打造招聘信息采集 Agent:
# skills/job-scraper/skill.yaml
name: job-scraper
version: 1.0.0
description: 从招聘网站采集符合条件的职位信息
triggers:
- keyword: "采集职位"
- cron: "0 8 * * 1-5" # 工作日早 8 点执行
capabilities:
- browser
- memory
parameters:
- name: keyword
type: string
description: 搜索关键词,如 "AI 工程师"
- name: city
type: string
description: 城市,如 "武汉"
- name: max_pages
type: number
default: 3
description: 最多采集页数
Agent 执行流程:
Agent(执行采集任务):
1. browser_navigate → 招聘网站搜索页
2. browser_fill → 输入搜索关键词 "AI 工程师"
3. browser_select → 选择城市 "武汉"
4. browser_click → 点击搜索按钮
5. browser_wait_for_selector → 等待结果列表加载
6. 循环采集(最多 3 页):
a. browser_evaluate → 提取职位名称、公司、薪资、要求
b. 记录到结构化数据
c. browser_click → 翻下一页
d. 等待加载
7. 去重 → 与 memory 中已有记录比对
8. 保存新职位到 memory/job-listings-2026-03-06.md
9. 生成日报摘要
10. 通过飞书/通知推送日报
总结:共采集 47 个职位,其中 12 个为新增,薪资范围 15k-35k。
memory 中的数据格式:
<!-- memory/job-listings-2026-03-06.md -->
# 招聘信息采集 - 2026-03-06
## 采集参数
- 关键词:AI 工程师
- 城市:武汉
- 来源:BOSS 直聘、猎聘
## 新增职位
### 1. AI 算法工程师 - 字节跳动
- 💰 薪资:25k-45k
- 📍 地点:武汉 · 光谷
- 📋 要求:3 年以上经验,熟悉 PyTorch/TensorFlow
- 🔗 链接:https://...
- 📅 发布日期:2026-03-05
### 2. NLP 工程师 - 腾讯
- 💰 薪资:20k-40k
- 📍 地点:武汉 · 光谷软件园
- 📋 要求:硕士以上,NLP 方向
- 🔗 链接:https://...
- 📅 发布日期:2026-03-06
...
注意事项与常见错误
浏览器自动化的常见错误:
| 常见错误 | 后果 | 正确做法 |
|---|---|---|
| 在无头模式下忽略视口大小 | 元素定位失败、截图不完整 | 显式设置 --window-size=1920,1080 |
| 未等待页面加载完成 | 操作目标元素不存在 | 使用智能等待而非固定 sleep |
| Cookie/Session 未持久化 | 每次都需重新登录 | 配置 user-data-dir 保持会话 |
注意事项与常见错误
浏览器自动化常见错误:
| 常见错误 | 后果 | 正确做法 |
|---|---|---|
| 忽略视口大小 | 元素定位失败 | 设置 window-size 参数 |
| 未等待页面加载 | 操作目标不存在 | 使用智能等待 |
| Session 未持久化 | 每次重新登录 | 配置 user-data-dir |
实操练习
🧪 练习 1:基础网页信息提取
目标:使用浏览器自动化提取 GitHub Trending 页面的热门仓库信息。
步骤:
- 确认 Browser Relay 已启动:
openclaw browser status
# 如未启动:openclaw browser start
- 在 Agent 对话中执行(或通过脚本实现):
请访问 https://github.com/trending 页面,提取今日热门仓库列表,
包括仓库名称、描述、星标数和编程语言。以表格形式展示前 10 个。
- 验证 Agent 输出应包含如下格式的表格:
| # | 仓库 | 描述 | Stars | 语言 |
|---|---|---|---|---|
| 1 | user/repo | … | 1,234 | Python |
验证要点:至少成功提取 5 个仓库信息,数据格式正确。
🧪 练习 2:实现一个自动化网页信息采集 Agent
目标:开发一个完整的信息采集 Skill,定时抓取指定网站内容并保存到 Memory。
任务要求:
- 创建 Skill 目录结构:
mkdir -p ~/.openclaw/workspace/skills/news-collector
cd ~/.openclaw/workspace/skills/news-collector
- 编写
skill.yaml配置:
name: news-collector
version: 1.0.0
description: 科技新闻采集,每日自动抓取并生成摘要
triggers:
- keyword: "采集新闻"
- cron: "0 8 * * *"
capabilities:
- browser
- memory
- 编写采集脚本
run.sh:
#!/bin/bash
# 科技新闻采集脚本
# 定义目标网站
SITES=(
"https://news.ycombinator.com"
"https://www.36kr.com/information/technology"
)
DATE=$(date +%Y-%m-%d)
OUTPUT="$HOME/.openclaw/workspace/memory/news-$DATE.md"
echo "# 科技新闻日报 - $DATE" > "$OUTPUT"
echo "" >> "$OUTPUT"
for site in "${SITES[@]}"; do
echo "📡 正在采集: $site"
# 使用 Browser Relay 提取内容
CONTENT=$(openclaw browser extract \
--url "$site" \
--mode "text" \
--max-chars 5000 \
--wait-for "body" \
--timeout 15000)
echo "## 来源: $site" >> "$OUTPUT"
echo "" >> "$OUTPUT"
echo "$CONTENT" >> "$OUTPUT"
echo "" >> "$OUTPUT"
echo "---" >> "$OUTPUT"
# 遵守速率限制
sleep 5
done
echo "✅ 采集完成,已保存到 $OUTPUT"
echo "📊 文件大小: $(wc -c < "$OUTPUT") 字节"
- 注册 Skill 并测试:
chmod +x run.sh
openclaw skill install ./
openclaw skill run news-collector
- 验证结果:
# 检查输出文件
cat ~/.openclaw/workspace/memory/news-$(date +%Y-%m-%d).md
# 确认 memory 文件已创建
ls -la ~/.openclaw/workspace/memory/news-*.md
验证要点:
- Skill 能成功安装和运行
- 采集脚本能访问目标网站并提取内容
- 采集结果以 Markdown 格式保存到 Memory 目录
- 速率控制生效(每个网站之间有延迟)
常见问题 (FAQ)
Q1: Browser Relay 启动失败,提示找不到 Chromium?
A: 需要安装 Chromium 浏览器:
# Ubuntu/Debian
sudo apt-get install -y chromium-browser
# CentOS/RHEL
sudo yum install -y chromium
# macOS
brew install --cask chromium
# 安装后更新配置中的路径
# config.json → browser.executablePath
如果系统中 Chromium 不在默认路径,使用 which chromium-browser 查找实际路径。
Q2: 页面加载后内容为空(JavaScript 渲染的页面)?
A: 许多现代网站使用 JavaScript 动态渲染内容。确保:
- 使用
waitUntil: "networkidle"等待所有网络请求完成 - 使用
browser_wait_for_selector等待特定元素出现 - 增大
timeout值给页面更多加载时间
await browser_navigate({
url: "https://example.com",
waitUntil: "networkidle",
timeout: 20000,
});
// 等待关键内容元素出现
await browser_wait_for_selector({
selector: ".main-content",
timeout: 10000,
});
Q3: 如何处理登录态保持?
A: Browser Relay 默认使用持久化的 User Data 目录。首次登录后,Cookie 会自动保存:
1. 通过 Agent 引导登录:
"请帮我打开 https://example.com/login 页面"
→ Agent 导航到登录页
→ Agent 填写用户名和密码
→ 提交登录
→ Cookie 自动持久化
2. 后续访问自动带上 Cookie:
"请帮我查看 https://example.com/dashboard"
→ 自动以登录状态访问
如果登录态频繁过期,检查网站是否使用了短 TTL 的 Session Cookie。
Q4: 截图模糊怎么办?
A: 调整设备像素比和视窗大小:
{
"browser": {
"defaultViewport": {
"width": 1920,
"height": 1080,
"deviceScaleFactor": 2
}
},
"screenshots": {
"quality": 95,
"format": "png"
}
}
deviceScaleFactor: 2 会生成 2 倍分辨率的截图,清晰度显著提升。
Q5: 浏览器占用内存过高?
A: Chromium 本身较占内存,建议:
- 限制最大并发页面数:
maxConcurrentPages: 3 - 用完及时关闭标签页
- 定期清理缓存:
openclaw browser clear-cache - 使用
--disable-extensions和--disable-gpu参数降低内存占用 - 监控内存使用:
openclaw browser status查看实时状态
参考来源
| 来源 | 链接 | 可信度 | 说明 |
|---|---|---|---|
| Playwright 官方文档 | https://playwright.dev/docs/intro | A | 浏览器, 自动化, Headless |
| OpenClaw 官方文档 | https://docs.OpenClaw.ai | A | 安装, 配置, 命令 |
| OpenClaw GitHub 仓库 | https://github.com/OpenClaw/OpenClaw | A | 源码, Issues, Release |
| ClawHub Skills 平台 | https://hub.OpenClaw.ai | A | Skills, 市场, 安装 |
本章小结
- Browser Relay 架构:OpenClaw 采用 Agent → Relay → Browser 三层架构,将浏览器操作与 Agent 推理解耦,提供请求队列、速率控制和页面缓存。
- 配置与启动:通过
~/.openclaw/browser-relay/config.json配置浏览器参数、速率限制、缓存策略,使用openclaw browser start/stop/status管理服务。 - 网页浏览与抓取:支持多种内容提取模式(text/html/markdown/structured/screenshot),可使用 CSS 选择器精准定位内容。
- 表单自动化:支持文本输入、下拉选择、复选框、文件上传等交互操作,可实现完整的表单填写流程。
- 截图与视觉分析:支持全页/区域/元素截图,结合 Vision 模型实现图表分析等场景。
- 合规使用:务必遵守 robots.txt、速率限制和法律法规,不绕过网站安全措施。
- Skill 结合:将浏览器操作封装为 Skill 可实现定时化、可复用的网页自动化任务。
- 遇到问题时,优先检查 Relay 状态(
openclaw browser status)和日志(~/.openclaw/browser-relay/logs/)。