网页监控:页面一变就通知你
💡 一句话总结:用 OpenClaw 建一位 7×24 小时的网页哨兵 —— 自动抓取、变化比对、变了才通知。
创作路线的第二课,解决「盯梢」问题:盯一个商品的价格、一个公告页、一个报名入口。这一课把 定时任务 Automations 的调度投递,和它的进阶形态条件触发器(官方叫 condition watcher)拼成一套流程——脚本定时抓页面 → 与上次快照比对 → 变了才唤醒 Claw → 写成通知投递进你的 IM。没变化的检查不烧模型回合,这是它和「让 AI 每隔几分钟看一眼页面」的本质区别,也是网页变化监控里成本最低的形态。全部示例基于 OpenClaw v2026.10.9。
学完你能做什么
- 建一条「页面一变就通知你」的监控任务:脚本自动抓取比对,变了才唤醒 Claw 写通知、投递进 IM
- 写自己的变化检测脚本:只比对圈定的字段(价格、库存、正文),不被广告位和时间戳误报
- 用首次触发做全链路冒烟测试,分清「强制 run 跳过门控」和「--due 尊重门控」
- 给监控加活动时段(半夜不响)和「响一次就收工」的一次性模式
为什么用 OpenClaw,而不是人肉刷新 / 网页版 AI?
| 能力 | 人肉刷新 / 网页版 AI | OpenClaw 条件监控 |
|---|---|---|
| 检查节奏 | ❌ 靠自觉定时去刷,刷十次九次白刷 | ✅ --every 30s 起自动评估,变没变它说了算 |
| 记住上次 | ❌ 网页版 AI 记不住上次的页面长什么样 | ✅ trigger.state 存上次快照,比对全自动 |
| 通知送达 | ❌ 变化躺在标签页里,错过就是错过 | ✅ 变了直接投递进 Telegram / 飞书 / 企业微信 |
| 没变化的成本 | ❌ 每查一次耗你一段时间 / 一个 AI 回合 | ✅ 没变化不唤醒模型,烧的只是一条 curl |
| 通知质量 | ❌ 「页面好像变了」,还得自己去看 | ✅ Claw 醒来重看页面,写清旧值新值和链接 |
你现在的困境
- 盯一个商品价格、一个公告页、一个报名入口,靠自己定时刷,刷十次九次没变化,真变了那次偏偏错过
- 试过整页比对的监控工具,广告位轮播、时间戳一变就疯狂误报,三天就把通知静音了
- 想让网页版 AI 帮忙盯,它记不住上次页面长什么样,每次都得你把页面贴给它
什么时候用这一招
当你需要:
- 盯一个具体页面:商品价格、库存状态、公告栏、版本发布页、报名入口
- 变化发生的第一时间收到一条「说人话」的网页更新提醒
而且不想:
- 每天手动刷十次页面,九次白刷
- 为一个页面去搭爬虫 + 定时脚本 + 推送服务
- 被整页字串比对工具的误报轰炸
💡 两种「盯」法,别选错
- 盯全网每天有什么新事 → 上一课 每日晨报 的
web_search方案 - 盯某个页面变没变 → 本课的条件触发器,脚本说 fire 才唤醒 Claw
需要登录才能看的页面,轻量抓取拿不到,参考 浏览器控制 的已登录会话思路。
🎒 开始前的准备
- 走完了 浏览器控制:知道哪些页面
web_fetch抓不动、什么时候得上浏览器(第 1 步直接用这个判断) - 认识 定时任务 Automations 的
--announce --channel --to投递写法(本课直接拼装,不重讲调度基础) - Gateway 正在运行,
openclaw automations list能正常列出任务 - 想收通知的 IM 渠道已接入(飞书、企业微信、Telegram 都行;暂时不接也能学,通知先落在运行历史里)
- Gateway 主机能跑
curl(触发脚本靠它抓页面) - 一杯水 ☕——约 12 分钟后,你的 IM 里会多一位 7×24 小时替你盯页面的哨兵
跟我做
第 1 步:选定目标页面,确认 Claw 抓得到
为什么:网页变化监控的第一道关不是配置,是确认这个页面「盯得了」。web_fetch 只做普通 HTTP GET 并抽取正文,不执行 JavaScript——JS 渲染出来的价格、库存,它抓回来的是空壳。
操作:在聊天里让 Claw 抓一次目标页面:
用 web_fetch 抓 https://example.com/product/123,把页面里的商品名和当前价格念给我听你应该看到:Claw 的回复里带商品名和价格。
抓回来是空壳、找不到价格?两种出路:
找页面的数据源:很多 JS 页面背后有 JSON 接口或 RSS,盯那个更稳
需要登录态的页面:轻量方案盯不了,回 浏览器控制 看已登录会话的思路
小检查:Claw 能念出页面上的关键信息(价格 / 标题 / 正文)
第 2 步:写变化检测脚本(watch-price.js)
为什么:条件触发器的核心是「变了才叫你」。变化检测交给脚本做——抓页面、抠字段、和上次的快照比对;没变化就返回 fire: false,模型继续睡,一次检查只花一条 curl。
新建 watch-price.js(按官方 PR CI 监控示例的模式写:抓取 → 比对 → 返回):
// watch-price.js —— 盯一个商品页的价格
// 改这两行就能盯你自己的页面
const url = "https://example.com/product/123";
const pricePattern = /¥\s*([0-9][0-9,.]*)/; // 按目标页面的真实结构改
const response = await exec({ command: "curl -sL --max-time 20 " + url });
if (response.status !== "completed" || response.exitCode !== 0) {
// 抓取失败要 throw,不要返回 fire: false
// 安静的监控看起来健康,其实已经瞎了
throw new Error("页面抓取失败:检查网络、URL 或站点反爬");
}
const html = response.aggregated;
const match = html.match(pricePattern);
if (!match) {
throw new Error("页面上找不到价格:页结构变了,或页面是 JS 渲染的空壳");
}
const price = match[1];
const old = trigger.state?.price;
const changed = old !== price;
return {
fire: changed,
...(changed
? { message: "价格变化:" + (old ?? "首次记录") + " → " + price }
: {}),
state: { price: price, url: url },
};三个关键约定(官方 Schedules 文档):
- 脚本必须返回
{ fire, message?, state? }:fire决定要不要唤醒模型,message会拼接进任务消息,state存下次比对的快照 - 上次的快照在
trigger.state里,上限 16 KB——只存抠出来的字段,别塞整页 HTML - 每次评估预算 30 秒、最多 5 次工具调用;触发任务内建最短间隔 30 秒
你应该看到:脚本已保存(比如存成 ~/.openclaw/watch-price.js),url 和 pricePattern 换成了你第 1 步验证过的页面。
⚠️ 触发脚本是无人值守的代码执行
官方安全说明:条件触发脚本默认以该 agent 的**完整工具策略(含 exec)**无人值守运行。只挂自己读过、看得懂的脚本;要硬停所有触发器,把 cron.triggers.enabled 设为 false。
- 小检查:脚本里的 URL 已换成自己的目标页,在主机上手动跑一遍
curl -sL <你的页面>能看到价格
第 3 步:创建网页变化监控任务(--trigger-script + 投递到 IM)
为什么:一条命令把「多久查一次、谁来判断变化、醒了干什么、通知发到哪」四件事一次定齐——网页变化监控需要的基础配置就这些。
openclaw automations add \
--name "价格监控" \
--every 5m \
--trigger-script ./watch-price.js \
--message "你盯的商品页价格有变化。用 web_fetch 打开页面核对当前价格,写一条中文通知:旧价格、新价格、涨了还是降了、商品链接、一句话值不值得入手。" \
--session isolated \
--announce \
--channel telegram \
--to "-1001234567890"逐个参数对号:
| 参数 | 作用 |
|---|---|
--every 5m | 每 5 分钟评估一次;触发任务内建最短间隔 30 秒,设得再密也会被抬到 30 秒 |
--trigger-script ./watch-price.js | 变化检测脚本;路径按一个 shell 参数传(带空格要加引号) |
--message "…" | 触发后 Claw 收到的任务提示词;脚本返回的 message 会拼接在它后面 |
--session isolated | 每次触发全新会话,不带历史包袱 |
--announce --channel telegram --to "…" | 通知投递,写法同晨报课 |
投递目标按渠道对号(细节见 每日晨报):
| 收到通知的地方 | 写法 |
|---|---|
| Telegram 群 | --to "-1001234567890" |
| Slack / Discord / Mattermost | --to "channel:<id>" 或 user:<id> |
| 飞书 / 企业微信 | 渠道接入见 飞书接入、企业微信接入 |
| 你本人的私聊 | 不写 --to,改用 --delivery-target owner |
你应该看到:创建成功,命令输出里能看到解析后的投递路由——目的地解析不了当场就报,不用等第一次触发才发现。
- 小检查:
openclaw automations show <job-id>里调度为 every 5m、触发脚本路径正确、投递路由解析正确
💡 这就是 OpenClaw 的独有价值
传统网页变化监控要么人肉刷,要么整页字串比对、误报满天飞。这里检测层你说了算(只比你在脚本里圈定的字段),通知层是 AI(Claw 醒来重看页面、写人话、给判断);没变化的检查不唤醒模型——一条 curl 的成本,换一个 7×24 小时的哨兵。
第 4 步:用首次触发做全链路冒烟测试
为什么:首次评估时 trigger.state 还是空的,比对结果一定是「变了」——所以建好任务后的第一次评估会天然触发一条通知。把它当冒烟测试:收到这条「首次记录」,说明抓取 → 触发 → 通知 → 投递全链路都通了。
急性子技巧:先把节奏设密一点试跑,通了再调回正常节奏(调度参数 add / edit 都认):
openclaw automations edit <job-id> --every 30s # 先 30 秒一查
openclaw automations runs <job-id> --limit 5 # 看运行历史
openclaw automations edit <job-id> --every 5m # 通了以后调回来你应该看到:一个评估周期内,IM 里收到第一条通知「价格变化:首次记录 → 1299」;runs 里这次运行状态为 ok。
之后页面没变化,监控就安静了——fire: false 的评估不产生运行历史,runs 不再新增不是任务挂了。
⚠️ 强制 run 会跳过门控
openclaw automations run <job-id> 默认强制运行,直接绕过触发脚本执行负载——页面没变也会触发通知。它只适合测「通知 + 投递」链路;要测门控本身,等一次调度评估,或到期时用 run <job-id> --due(尊重门控,也不会让任务提前到期)。
- 小检查:IM 收到过第一条「首次记录」通知;能说出
runs不再新增为什么不是故障
第 5 步:调教通知的口味(提示词就是通知的人设)
为什么:默认通知是「醒了、看了、写了」的即兴发挥,格式每次飘。通知的人设就是任务提示词,edit 换掉它,任务不用重建。
openclaw automations edit <job-id> --message "<把下面魔法 Prompt 里的完整版贴进来>"调教三要点:
- 旧值新值写清楚:脚本
message里已带「旧 → 新」,提示词里规定它必须出现在通知里 - 口吻写死:通知是给推送扫一眼的人看的,限字数、给结构
- 取舍写死:涨价也报还是只报降价?降到目标价才值得说?写进约束
你应该看到:edit 成功后 show 里的 message 已更新;下次真变化触发时,通知格式就是你定的样子。
- 小检查:提示词里写死了输出结构和「只报什么」的取舍
📋 魔法 Prompt
这一页的「Prompt」是任务提示词——第 3 步命令里 --message 的那个位置,或第 5 步 edit --message 换进去的完整版。触发时脚本返回的 message(旧值 → 新值)会拼接在它后面,一起交给 Claw。
📝 价格变化通知
预期效果:价格一变,IM 里收到一条 80 字内、带链接、带建议的通知——旧价格、新价格、涨降方向一眼看清。
## 角色
你是价格监控助手,负责把商品页的价格变化写成一眼看懂的通知。
## 任务
根据触发消息里的旧价格和新价格,用 web_fetch 打开商品页核对当前价格,写一条中文变化通知。
## 输入信息
### 必填项
- 商品页链接:【脚本里配置的 URL】
- 旧价格与新价格:【触发消息里已带,如「价格变化:首次记录 → 1299」】
### 选填项
- 目标价:【降到这个价以下才提醒我?】
- 关注理由:【为什么盯这个商品,如「历史低位是 999」?】
## 输出规范
一条不超过 80 字的中文通知:商品名 + 旧价格 → 新价格(涨/降)+ 商品链接 + 一句话建议
## 约束条件
- ✅ 价格与页面核对一致才发,中文叙述、数字保持原样
- ✅ 降到目标价以下时,在建议里明确说
- ❌ 不编造页面上看不到的信息(库存、优惠券)
- ❌ 核对失败就如实写「价格待核对」,不猜📋 页面更新摘要(盯公告 / 版本页)
预期效果:公告页、版本发布页一有新内容,收到 1-3 条「这次变了什么」的摘要,而不是「页面有变化」四个字。配套脚本改法:把 watch-price.js 里「抠价格」换成「抠你关心的段落」(比如版本记录区),state 存这段文本;段落太长存不下 16 KB,就只存它的哈希值——反正 Claw 醒来会重新抓页面看细节。
## 角色
你是更新情报员,负责盯一个页面的内容变化并写成摘要通知。
## 任务
触发消息说页面变了;用 web_fetch 抓取页面,找出这次变化对应的新内容,写成中文更新摘要。
## 输入信息
### 必填项
- 页面链接:【脚本里配置的 URL】
### 选填项
- 只关心的部分:【如「版本发布记录」「公告栏」?】
- 变化关键词:【如 release、开放申请、降价?】
## 输出规范
- 第一行:📋 页面更新 ·【页面名】
- 变化摘要 1-3 条:每条一句话 + 页面原文关键句
- 末尾附页面链接,全文不超过 120 字
## 约束条件
- ✅ 只报页面上真实出现的内容,中文叙述、专有名词保持原文
- ✅ 摘要聚焦「这次的变化」,不是页面内容大全
- ❌ 不把页面上一直有的旧内容当成这次的变化
- ❌ 不编造链接和日期检查点 ✅
- 目标页面
web_fetch抓得到关键信息;JS 空壳页换成了数据源或 RSS openclaw automations list里有「价格监控」,触发脚本路径、投递路由都正确- 收到过第一条「首次记录」通知——抓取、触发、通知、投递全链路已验证
- 能说出强制
run和run --due的区别(一个绕过门控,一个尊重门控) - 盯的页面把
tools.web.fetch.cacheTtlMinutes设成 0,通知不会被 15 分钟缓存喂旧页
踩坑提醒
❌ 强制 run 试跑,页面没变却收到了通知
原因:run <job-id> 默认强制运行,绕过触发脚本直接执行负载——这是官方设计,本意是让你随时验证投递链路。
正确做法:测门控等一次调度评估,或到期时 run <job-id> --due。别把强制 run 的「误触发」当成脚本写错了。
❌ 抓取失败返回 fire: false,监控「安静得可怕」
原因:官方明确要求观测失败要 throw,别转成 fire: false——失败被当成「没变化」,监控瞎了看起来还健康,错误也进不了告警路径。
正确做法:像上面的脚本那样,抓取失败、抠不到字段都 throw new Error(...),让失败作为可操作的调度错误暴露出来。
❌ 通知里 Claw 看到的还是旧页面
原因:web_fetch 的结果默认缓存 15 分钟(cacheTtlMinutes 默认 15)。第 1 步手动抓过、或 15 分钟内触发过,Claw 醒来再 web_fetch 同一个 URL,拿到的可能是缓存里的旧页。
正确做法:监控页把缓存关掉——tools.web.fetch.cacheTtlMinutes: 0 对读写都绕过缓存。注意脚本里的 curl 不走这个缓存,受影响的是 Claw 醒来用 web_fetch 看页面的那一步。
❌ 盯的是 JS 渲染页,脚本永远抓到空壳
原因:web_fetch 和 curl 都不执行 JavaScript,价格由 JS 算出来的页面,抓回来的 HTML 里根本没有。
正确做法:盯页面的 JSON 接口或 RSS 数据源;实在要登录态,回 浏览器控制 的思路。第 1 步先验证,就是为了不在这里翻车。
进阶技巧(可选)
降到目标价才响,响一次就收工。 抢购、开售提醒这类「响一次就够」的场景:脚本里加阈值判断(把价格解析成数字再比),再用官方的 once: true 语义——首次成功触发的负载跑完后,任务自动禁用,不用记得手动关。
半夜别响:活动时段。 监控任务支持 --active-hours-start 08:00 --active-hours-end 22:00 --active-hours-timezone user,还有 --idle-only 空闲才跑。窗口外的检查会跳过,但变化不会丢:state 记着上一次的样子,早上窗口一开,第一次评估就把夜里发生的变化报出来。
聊天里一句 /loop 起轻量盯梢。 /loop [间隔] <提示词> 在当前会话直接建循环任务(会话所有者专用;/loop status 查看、/loop stop 停)。省略间隔时它在 1 分钟到 1 小时之间自调节奏。注意 /loop 没有触发脚本的变化检测——每轮都唤醒模型,适合低频「看一眼有没有新公告」;真·变化检测还是用本课的 --trigger-script。
安全阀门。 条件触发脚本、stream 监控和脚本负载共用一个总开关:cron.triggers.enabled: false 一键硬停,设回 true 恢复。
本课小结
✅ 你现在能:
- 建一条「页面一变就通知你」的网页变化监控任务:脚本检测、Claw 写通知、
--announce投递进 IM - 写变化检测脚本:
exec抓页面、抠字段、与trigger.state比对,返回{ fire, message?, state? } - 用首次触发冒烟测试全链路,分清强制
run(绕过门控)和--due(尊重门控) - 用活动时段、
once: true和缓存关闭,把监控调得又省又安静
关键配置回顾:
| 配置 | 推荐值 | 说明 |
|---|---|---|
--every | 5m(下限 30s) | 检查节奏;触发任务内建最短间隔 30 秒 |
--trigger-script | ./watch-price.js | 变化检测脚本;路径按一个 shell 参数引用 |
trigger.state | 只存抠出的字段 | 快照上限 16 KB;评估预算 30 秒 / 5 次工具调用 |
--session | isolated | 每次触发全新会话 |
--announce --channel --to | 按渠道对号 | 同晨报课:Telegram 群 -100…,Slack/Discord channel:<id>,发本人 --delivery-target owner |
tools.web.fetch.cacheTtlMinutes | 0 | 监控页绕过 15 分钟缓存,通知不喂旧页 |
下一课预告
这一课的哨兵只会「说」——文字通知甩进群里。下一课 图片与语音:给内容配图、把文章转语音,让 Claw 的产出有声有色。
你会学到:
- 给内容配图:OpenClaw 的图片生成怎么用
- 把文章转语音:TTS 让长文变成能听的音频
- OpenClaw 的语音能力还能怎么玩