OpenClaw 浏览器自动化实战指南
浏览器自动化是 OpenClaw 最强大的功能之一。通过 browser 工具,你可以实现网页抓取、自动化测试、数据收集等复杂任务。本文通过 5 个实战案例,详细讲解如何使用浏览器自动化解决实际问题。
一、工具概述
browser 工具能力
- 页面导航:打开网页、跳转链接
- 元素交互:点击、输入、选择、悬停
- 内容提取:截图、快照、执行 JavaScript
- 文件操作:上传、下载
- 多标签管理:打开、关闭、切换标签页
基本用法
javascript
// 打开网页
browser(action="open", url="https://example.com")
// 获取页面快照(查看可交互元素)
browser(action="snapshot", refs="aria")
// 点击元素
browser(action="act", kind="click", ref="e12")
// 输入文本
browser(action="act", kind="type", ref="e15", text="搜索内容")
// 截图
browser(action="screenshot", path="./screenshot.png")二、实战案例 1:自动抓取百度热搜
场景说明
每天早晨自动抓取百度热搜榜前 10 条新闻,保存到本地并发送到飞书群。
完整实现
javascript
// 1. 打开百度热搜
browser(action="open", url="https://hot.baidu.com/")
// 2. 等待页面加载
browser(action="act", kind="wait", loadState="networkidle", timeoutMs=10000)
// 3. 获取页面快照,查看元素结构
snapshot = browser(action="snapshot", refs="aria")
console.log("页面元素:", snapshot)
// 4. 提取热搜数据(使用 JavaScript)
hotSearchData = browser(action="act", kind="evaluate",
fn=`() => {
const items = document.querySelectorAll('.hot-item');
return Array.from(items.slice(0, 10)).map((item, index) => ({
rank: index + 1,
title: item.querySelector('.title')?.innerText || '',
heat: item.querySelector('.heat')?.innerText || '',
trend: item.querySelector('.trend')?.className || ''
}));
}`
)
// 5. 格式化输出
report = \`
📊 百度热搜榜 - \${new Date().toLocaleDateString('zh-CN')}
\${hotSearchData.map(item =>
\`\${item.rank}. \${item.title} 🔥 \${item.heat}\`
).join('\\n')}
数据抓取时间:\${new Date().toLocaleTimeString('zh-CN')}
\`
// 6. 保存到文件
write(
path="./baidu-hot-search.md",
content=report
)
// 7. 截图保存
browser(action="screenshot", path="./baidu-hot-screenshot.png")
// 8. 发送到飞书群
message(
action="send",
channel="feishu",
target="chat_team",
message=report,
media="./baidu-hot-screenshot.png"
)
console.log("✅ 热搜抓取完成!")输出示例
📊 百度热搜榜 - 2026/3/19
1. 2026 年高考报名人数公布 🔥 1234.5 万
2. 新一代人工智能模型发布 🔥 987.3 万
3. 新能源汽车销量创新高 🔥 756.2 万
4. ...
数据抓取时间:08:00:15定时任务配置
javascript
cron(
action="add",
job={
name: "每日百度热搜抓取",
schedule: {
kind: "cron",
expr: "0 8 * * *", // 每天 8:00
tz: "Asia/Shanghai"
},
payload: {
kind: "agentTurn",
message: "执行百度热搜抓取流程",
timeoutSeconds: 300
},
sessionTarget: "isolated"
}
)三、实战案例 2:自动化表单提交
场景说明
批量注册测试账号,自动填写表单并提交。
完整实现
javascript
// 测试账号数据
const testAccounts = [
{ email: "test1@example.com", password: "Test1234!", name: "测试用户 1" },
{ email: "test2@example.com", password: "Test1234!", name: "测试用户 2" },
{ email: "test3@example.com", password: "Test1234!", name: "测试用户 3" }
]
// 注册函数
async function registerAccount(account) {
console.log(`开始注册:\${account.email}`)
// 1. 打开注册页面
browser(action="open", url="https://example.com/register")
// 2. 等待页面加载
browser(action="act", kind="wait", selector="#register-form", timeoutMs=10000)
// 3. 填写表单
browser(action="act", kind="fill", ref="name-input", text=account.name)
browser(action="act", kind="fill", ref="email-input", text=account.email)
browser(action="act", kind="fill", ref="password-input", text=account.password)
browser(action="act", kind="fill", ref="confirm-password-input", text=account.password)
// 4. 勾选协议
browser(action="act", kind="click", ref="agree-checkbox")
// 5. 提交表单
browser(action="act", kind="click", ref="submit-button")
// 6. 等待注册成功
browser(action="act", kind="wait", text="注册成功", timeoutMs=15000)
// 7. 截图保存
browser(action="screenshot", path=`./register-\${account.email}.png`)
console.log(`✅ 注册成功:\${account.email}`)
return { email: account.email, status: "success" }
}
// 批量注册
const results = []
for (const account of testAccounts) {
try {
const result = await registerAccount(account)
results.push(result)
// 等待 2 秒,避免触发反爬
exec(command="sleep 2")
} catch (e) {
results.push({
email: account.email,
status: "failed",
error: e.message
})
console.log(`❌ 注册失败:\${account.email} - \${e.message}`)
}
}
// 生成报告
const report = \`
# 批量注册报告
总账号数:\${testAccounts.length}
成功:\${results.filter(r => r.status === "success").length}
失败:\${results.filter(r => r.status === "failed").length}
## 详细结果
\${results.map(r =>
\`- \${r.email}: \${r.status} \${r.error ? '(' + r.error + ')' : ''}\`
).join('\\n')}
\`
write(path="./register-report.md", content=report)注意事项
避免触发反爬
- 添加随机延迟(2-5 秒)
- 使用不同的 User-Agent
- 控制注册频率
错误处理
- 捕获异常,继续执行
- 记录失败原因
- 支持重试机制
数据清理
- 测试完成后删除测试账号
- 不保留敏感信息
四、实战案例 3:网站监控告警
场景说明
监控竞争对手网站,发现价格变化或新活动时立即告警。
完整实现
javascript
// 监控配置
const monitoringConfig = {
url: "https://competitor.com/products",
checkInterval: 3600000, // 1 小时
priceSelector: ".price",
activitySelector: ".promotion-banner"
}
// 检查函数
async function checkWebsite() {
console.log("开始检查网站...")
// 1. 打开网站
browser(action="open", url=monitoringConfig.url)
// 2. 等待加载
browser(action="act", kind="wait", loadState="networkidle", timeoutMs=10000)
// 3. 提取价格信息
const prices = browser(action="act", kind="evaluate",
fn=`() => {
const elements = document.querySelectorAll('\${monitoringConfig.priceSelector}');
return Array.from(elements).map(el => el.innerText.trim());
}`
)
// 4. 检查是否有新活动
const hasActivity = browser(action="act", kind="evaluate",
fn=`() => {
const banner = document.querySelector('\${monitoringConfig.activitySelector}');
return banner ? banner.innerText.trim() : null;
}`
)
// 5. 读取上次检查结果
let lastCheck = { prices: [], activity: null }
try {
lastCheck = JSON.parse(read(path="./last-check.json"))
} catch (e) {
// 首次检查
}
// 6. 比较变化
const priceChanged = JSON.stringify(prices) !== JSON.stringify(lastCheck.prices)
const newActivity = hasActivity && hasActivity !== lastCheck.activity
// 7. 生成报告
const report = {
timestamp: new Date().toISOString(),
prices,
hasActivity,
priceChanged,
newActivity
}
// 8. 保存检查结果
write(path="./last-check.json", content=JSON.stringify(report, null, 2))
// 9. 如有变化,发送告警
if (priceChanged || newActivity) {
const alertMessage = \`
🚨 网站监控告警
时间:\${new Date().toLocaleString('zh-CN')}
变化类型:\${priceChanged ? '价格变化' : ''} \${newActivity ? '新活动' : ''}
当前价格:
\${prices.map(p => '- ' + p).join('\\n')}
\${hasActivity ? '当前活动:' + hasActivity : ''}
请立即查看:\${monitoringConfig.url}
\`
message(
action="send",
channel="feishu",
target="chat_product_team",
message=alertMessage
)
console.log("⚠️ 发现变化,已发送告警")
} else {
console.log("✅ 无变化")
}
return report
}
// 执行检查
await checkWebsite()告警示例
🚨 网站监控告警
时间:2026-03-19 14:30:00
变化类型:价格变化
当前价格:
- ¥299 (原价 ¥399)
- ¥199 (原价 ¥249)
- ¥599 (不变)
请立即查看:https://competitor.com/products五、实战案例 4:批量截图工具
场景说明
批量抓取多个页面的截图,用于设计参考或竞品分析。
完整实现
javascript
// 页面列表
const pages = [
"https://example.com/home",
"https://example.com/products",
"https://example.com/about",
"https://competitor.com/home",
"https://competitor.com/products"
]
// 批量截图
async function batchScreenshot(pages, outputDir="./screenshots") {
// 创建输出目录
exec(command=`mkdir -p \${outputDir}`)
const results = []
for (let i = 0; i < pages.length; i++) {
const url = pages[i]
const filename = url.replace(/[^a-zA-Z0-9]/g, '_') + '.png'
const filepath = `\${outputDir}/\${filename}`
console.log(`[\${i+1}/\${pages.length}] 截图:\${url}`)
try {
// 打开页面
browser(action="open", url=url)
// 等待加载
browser(action="act", kind="wait", loadState="networkidle", timeoutMs=10000)
// 截图(全页面)
browser(action="screenshot", path=filepath, fullPage=true)
results.push({ url, filepath, status: "success" })
console.log(`✅ 完成:\${url}`)
} catch (e) {
results.push({ url, status: "failed", error: e.message })
console.log(`❌ 失败:\${url} - \${e.message}`)
}
// 延迟,避免请求过快
if (i < pages.length - 1) {
exec(command="sleep 2")
}
}
// 生成报告
const report = \`
# 批量截图报告
总页面数:\${pages.length}
成功:\${results.filter(r => r.status === "success").length}
失败:\${results.filter(r => r.status === "failed").length}
## 成功列表
\${results.filter(r => r.status === "success").map(r =>
\`- [\${r.url}](\${r.filepath})\`
).join('\\n')}
## 失败列表
\${results.filter(r => r.status === "failed").map(r =>
\`- \${r.url}: \${r.error}\`
).join('\\n')}
\`
write(path=`\${outputDir}/report.md`, content=report)
return results
}
// 执行
await batchScreenshot(pages)六、高级技巧
1. 使用 Aria 标签精确定位
javascript
// 获取 aria 标签(更稳定)
browser(action="snapshot", refs="aria")
// 返回示例:
// e12="搜索按钮"
// e15="搜索输入框"
// e20="提交按钮"
// 精确点击
browser(action="act", kind="click", ref="e12")2. 处理弹窗
javascript
// 等待弹窗并接受
browser(action="dialog", accept=true)
// 或处理确认对话框
browser(action="act", kind="wait", text="确定要删除吗?")
browser(action="act", kind="click", ref="confirm-button")3. 执行自定义 JavaScript
javascript
// 滚动到页面底部
browser(action="act", kind="evaluate",
fn="() => window.scrollTo(0, document.body.scrollHeight)")
// 获取所有链接
browser(action="act", kind="evaluate",
fn="() => Array.from(document.querySelectorAll('a')).map(a => a.href)")
// 修改页面样式(用于调试)
browser(action="act", kind="evaluate",
fn="() => document.body.style.background = 'red'")4. 文件上传
javascript
// 上传文件
browser(action="upload", paths=["./test-file.pdf"])
// 多文件上传
browser(action="upload", paths=["./file1.pdf", "./file2.pdf"])七、常见问题
Q: 元素找不到怎么办?
A:
- 增加等待时间:
browser(action="wait", timeoutMs=30000) - 检查元素是否在 iframe 内
- 使用 aria 标签而非选择器
- 截图查看当前页面状态
Q: 点击被拦截怎么办?
A:
javascript
// 先滚动到元素位置
browser(action="act", kind="evaluate",
fn="() => document.querySelector('#target').scrollIntoView()")
// 再尝试点击
browser(action="act", kind="click", ref="e12")Q: 如何处理验证码?
A:
- 截图验证码区域
- 发送给用户识别
- 或使用第三方打码平台
- 简单验证码可用 OCR 识别
javascript
// 截图验证码
browser(action="screenshot", selector="#captcha", path="./captcha.png")
// 发送给用户
message(action="send", media="./captcha.png", message="请识别验证码")Q: 网站有反爬措施怎么办?
A:
- 添加随机延迟(2-5 秒)
- 限制请求频率
- 使用 User-Agent 轮换
- 考虑使用官方 API
八、总结
浏览器自动化是提升效率的利器:
| 场景 | 实现方式 |
|---|---|
| 数据抓取 | evaluate + JavaScript |
| 表单提交 | fill + click |
| 网站监控 | 定期执行 + 对比变化 |
| 批量截图 | screenshot + 循环 |
掌握这些技巧,你可以:
- 自动化重复的网页操作
- 批量收集网络数据
- 实时监控网站变化
- 自动测试网页功能
记住:自动化应该节省时间,而不是制造新问题!
相关资源: