changedetection.io 0.60.9 进阶实战与运维

changedetection.io 0.60.9 进阶实战与运维手册,含 CSS/XPath/JSON 过滤器、REST API 全端点、通知渠道、RSS、备份恢复演练、升级回滚与故障排查,全部环节实测验证。

changedetection.ioUbuntuUbuntu 22.04Linux监控2026/10/17

changedetection.io 0.60.9 进阶实战与运维

目标:面向已跑通基础使用的读者,沉淀进阶实战(过滤器、API、通知、RSS、浏览器渲染)与运维动作(备份恢复、升级回滚、巡检排障)。全部端点与命令在 0.60.9 实测环境验证,回显为实测原文。

演示环境:Ubuntu 22.04 上以 pip 方式安装的 changedetection.io 0.60.9(systemd 托管,端口 5000,数据目录 /opt/changedetection/data);监控目标为自建演示页(价格页 monitor-test.html、表格页 table.html、JSON 接口 status.json)。API key 为 5521439027a85d13458e92c9c11b0cda(Settings → API 页获取)。

一、环境信息

项目实测值
版本changedetection.io 0.60.9
部署形态pip + venv + systemd(裸机部署形态;涉及浏览器渲染的章节同样适用于 Compose 形态)
演示监控价格监控 c7995f0b-253d-4736-86b4-7fad08b927c6(CSS 过滤)、表格监控 3e068380-69e0-41af-8bba-3dc16250e6c7(XPath 过滤)、JSON 监控 909d2621-04cc-4604-8bef-878e5391d628(json 过滤)
通知接收器本地 json://127.0.0.1:9000/changedetection

二、前置条件

  • 服务运行正常:systemctl is-active changedetection 输出 active;
  • API key 已获取(本篇所有 curl 均带 -H "x-api-key: 5521439027a85d13458e92c9c11b0cda");
  • 涉及浏览器渲染的章节需已部署独立 Chrome 渲染服务(sockpuppetbrowser,部署见《changedetection.io 0.60.9 Docker Compose 部署指南》)。

三、过滤器进阶实战

3.1 三种过滤器的完整实测记录

三种主流过滤器在演示页上的实测结果汇总(操作细节见快速入门第五节):

监控目标过滤器页面改动检出结果
价格页 #price(CSS)#price¥129.00 → ¥139.00快照只剩 ¥139.00,其他字段变化不触发
表格状态列(XPath)xpath://tr/td[@class="state"]节点二"运行中"→"已停止"快照只剩状态列 运行中 / 已停止
JSON 接口(JSONPath)json:priceprice 129.00 → 99.00差异输出 (changed) 129.0 / (into) 99.0

3.2 快照存储机制(理解过滤器的基础)

每个监控的历史快照以纯文本形式存放在其 UUID 目录内,文件名为内容特征值。实测 API 返回的快照索引:

curl -s -H "x-api-key: 5521439027a85d13458e92c9c11b0cda" http://127.0.0.1:5000/api/v1/watch/909d2621-04cc-4604-8bef-878e5391d628/history

实测回显:

{
    "1792204319": "/opt/changedetection/data/909d2621-04cc-4604-8bef-878e5391d628/3eefd8b80a0c3d90738102cecb1801d7.txt",
    "1792204342": "/opt/changedetection/data/909d2621-04cc-4604-8bef-878e5391d628/695b1e4ea14a79745f55805749ce85e4.txt",
    "1792204420": "/opt/changedetection/data/909d2621-04cc-4604-8bef-878e5391d628/4a0de962414199fbda294c3b4949cdc6.txt"
}

键是 Unix 时间戳(检查时刻),值是快照文件路径。两个要点:

  • 过滤器改变后建议重新建基线:快照记录的是"抓取当时"过滤后的内容,中途加/改过滤器会让新旧快照口径不一致,产生一次"伪变更";
  • 不要直接 cat 快照文件:部分文件内容经过编码处理,直接查看可能是乱码,统一用 API 读取(见 4.6 节)。

3.3 移除元素与文本预处理组合

实战中过滤器经常要"正反结合":

  • CSS/JSONPath/JQ/XPath Filters(正向保留):只看选中区域;
  • Remove elements(反向剔除):如 div.ads,div.timestamp 先删广告与时间戳,再进差异对比;
  • 文本预处理开关(Filters & Triggers 页底部):Sort text alphabetically(排序)、Trim whitespace before and after text(去首尾空白)、Remove duplicate lines of text(去重)、Strip ignored lines(剔除匹配行)。

推荐组合示例——监控商品列表页:Remove elements 剔除轮播图与倒计时,过滤器保留主列表容器,再开启排序与去重,可把噪音告警压到最低。

四、REST API 全套实战

4.1 认证方式

请求头 x-api-key 携带 token。错误凭证的实测响应(无 key 或错误 key 均为 403):

curl -s -w "\nHTTP=%{http_code}\n" http://127.0.0.1:5000/api/v1/watch

实测回显:

"Invalid access - API key invalid."

HTTP=403

4.2 端点总表(全部实测)

方法路径作用实测响应
POST/api/v1/watch创建监控201 + {"uuid": "<uuid>"}
GET/api/v1/watch列出全部监控200 + 监控字典
GET/api/v1/watch/<uuid>监控详情(url/last_checked/last_error 等)200
GET/api/v1/watch/<uuid>?recheck=true触发单个重检"OK"
GET/api/v1/watch?recheck_all=true全部监控入队重检{"status": "OK, queued 3 watches for rechecking (1 already queued or running)"}
PUT/api/v1/watch/<uuid>修改监控配置"OK"
GET/api/v1/watch/<uuid>/history快照索引(时间戳→文件路径)200
GET/api/v1/watch/<uuid>/history/<ts>读取指定快照200 + 快照文本
GET/api/v1/watch/<uuid>/difference/<from>/<to>两快照差异文本200 + (changed)/(into) 文本
DELETE/api/v1/watch/<uuid>删除监控204

⚠️ 实测踩坑:修改配置必须用 PUT。用 PATCH 提交 {"recheck": true} 得到 405(实测回显 {"message": "The method is not allowed for the requested URL."},HTTP=405);触发重检的正确姿势是 GET 带 ?recheck=true,而不是 PATCH/POST recheck 字段。

4.3 创建监控(带过滤器与检查间隔)

一次 POST 可同时指定 URL、过滤器、检查间隔(间隔单位为周/天/时/分/秒):

curl -s -H "x-api-key: 5521439027a85d13458e92c9c11b0cda" -X POST -H "Content-Type: application/json" -d '{"url": "http://127.0.0.1:8000/table.html", "include_filters": ["#data-table"], "time_between_check": {"weeks": 0, "days": 0, "hours": 1, "minutes": 30, "seconds": 0}}' http://127.0.0.1:5000/api/v1/watch

实测回显:

{"uuid": "c9ac5b3c-cd6c-4fda-9dcf-ecc9c43ddb38"}

读取详情确认参数已生效:

curl -s -H "x-api-key: 5521439027a85d13458e92c9c11b0cda" http://127.0.0.1:5000/api/v1/watch/c9ac5b3c-cd6c-4fda-9dcf-ecc9c43ddb38 | python3 -c "import json,sys; d=json.load(sys.stdin); print(json.dumps({k: d.get(k) for k in ('include_filters','time_between_check')}, ensure_ascii=False))"

实测回显:

{"include_filters": ["#data-table"], "time_between_check": {"weeks": 0, "days": 0, "hours": 1, "minutes": 30, "seconds": 0}}

💡 说明:创建请求中的 tag 字段在部分参数组合下不生效(实测带 include_filters+time_between_check 的请求返回详情里 tag 为空字符串),分组建议创建后在界面编辑页的 Group Tag 字段补上,或创建后用 PUT 修改。

4.4 修改与重检

修改过滤器(PUT,实测响应):

curl -s -H "x-api-key: 5521439027a85d13458e92c9c11b0cda" -X PUT -H "Content-Type: application/json" -d '{"include_filters": ["#price"]}' http://127.0.0.1:5000/api/v1/watch/c7995f0b-253d-4736-86b4-7fad08b927c6

实测回显:

"OK"

触发单监控重检:

curl -s -H "x-api-key: 5521439027a85d13458e92c9c11b0cda" "http://127.0.0.1:5000/api/v1/watch/c7995f0b-253d-4736-86b4-7fad08b927c6?recheck=true"

实测回显:

"OK"

触发全部重检(巡检/迁移后常用):

curl -s -H "x-api-key: 5521439027a85d13458e92c9c11b0cda" "http://127.0.0.1:5000/api/v1/watch?recheck_all=true"

实测回显:

{"status": "OK, queued 3 watches for rechecking (1 already queued or running)"}

4.5 读取快照与差异

读指定快照(时间戳从 history 索引取,实测取 1792204342):

curl -s -H "x-api-key: 5521439027a85d13458e92c9c11b0cda" http://127.0.0.1:5000/api/v1/watch/909d2621-04cc-4604-8bef-878e5391d628/history/1792204342

实测回显(JSON 监控经 json:price 过滤后的快照就是价格数字):

99.0

读两个时间戳之间的差异:

curl -s -H "x-api-key: 5521439027a85d13458e92c9c11b0cda" "http://127.0.0.1:5000/api/v1/watch/909d2621-04cc-4604-8bef-878e5391d628/difference/1792204319/1792204342"

实测回显:

(changed) 129.0
(into) 99.0

4.6 删除监控

curl -s -o /dev/null -w "DELETE HTTP=%{http_code}\n" -H "x-api-key: 5521439027a85d13458e92c9c11b0cda" -X DELETE http://127.0.0.1:5000/api/v1/watch/c9ac5b3c-cd6c-4fda-9dcf-ecc9c43ddb38

实测回显:

DELETE HTTP=204

4.7 批量巡检脚本(自动化联动示例)

以下 Python 脚本演示"列出监控 → 判断健康状态"的巡检逻辑(程序示例,保存为 inspect_watch.py 后用 python3 inspect_watch.py 运行):

import json
import urllib.request

BASE = "http://127.0.0.1:5000"
KEY = "5521439027a85d13458e92c9c11b0cda"

def api(path):
    req = urllib.request.Request(BASE + path, headers={"x-api-key": KEY})
    return json.load(urllib.request.urlopen(req))

watches = api("/api/v1/watch")
for uuid, w in watches.items():
    status = "ERROR: " + w["last_error"] if w.get("last_error") else "ok"
    print(f"{uuid} | {w['url']} | {status}")

实测回显(本机演示实例;最后一条外网监控因该服务器未放行外网访问而带真实报错,正是巡检要发现的问题):

909d2621-04cc-4604-8bef-878e5391d628 | http://127.0.0.1:8000/status.json | ok
c7995f0b-253d-4736-86b4-7fad08b927c6 | http://127.0.0.1:8000/monitor-test.html | ok
3e068380-69e0-41af-8bba-3dc16250e6c7 | http://127.0.0.1:8000/table.html | ok
aa927fec-85d5-481d-b736-ce1896d61de7 | https://changedetection.io/CHANGELOG.txt | ERROR: Exception: cannot schedule new futures after shutdown
39173cab-8b03-4d9a-8137-94610864cbed | https://news.ycombinator.com/ | ok

💡 说明:last_error 只保留最近一次检查的错误,"cannot schedule new futures after shutdown" 多出现于服务重启过程中的检查被中断,重检一次即可恢复;巡检脚本对这类偶发错误可先自动触发 ?recheck=true 再确认。

五、通知渠道实战

5.1 渠道配置回顾

通知 URL 写法(Apprise schema)与选型对比见《changedetection.io 0.60.9 快速入门(添加监控到差异告警)》第七节。本节聚焦实测与进阶。

5.2 实测:json:// Webhook 端到端

配置(单监控 Notifications 页或全局):

Notification URL List: json://127.0.0.1:9000/changedetection
Notification Title: 变更告警 - {{watch_title}}
Notification Body: 监控目标 {{watch_url}} 检测到变化:{{diff}}

把 JSON 监控的价格从 99.00 改为 88.00 并重检后,本地接收器收到的报文(实测原文):

{"version": "1.0", "title": "\u53d8\u66f4\u544a\u8b66 - http://127.0.0.1:8000/status.json", "message": "\u76d1\u63a7\u76ee\u6807 http://127.0.0.1:8000/status.json \u68c0\u6d4b\u5230\u53d8\u5316\uff1a<span style=\"background-color: #fadad7; color: #b30000;\" role=\"note\" aria-label=\"Changed text\" title=\"Changed text\">99.0</span><br>\n<span style=\"background-color: #eaf2c2; color: #406619;\" role=\"note\" aria-label=\"Changed into\" title=\"Changed into\">88.0</span>", "attachments": [], "type": "info"}

要点:message 中差异自带 HTML 着色(红底旧值/绿底新值);中文被转义为 Unicode(\u53d8\u66f4... = "变更..."),接收端按标准 JSON 解析即可还原。

5.3 通知触达控制

  • 通知频率与条件(单监控 Notifications 页):可限制只在"变化时/失败时/恢复时"发;
  • 临时静音:列表行内 mute 按钮(批量 Mute notifications),静音期间不发送但照常记录差异;
  • 测试通道:Settings → Notifications 页的测试发送按钮,先验证渠道连通再上业务。

六、RSS 输出实战

6.1 获取 RSS 地址

RSS token 存于数据目录 changedetection.json 的 settings.application.rss_access_token(实测值 80dadc72cf602324fd276e496cd91cac),feed 地址格式:

http://127.0.0.1:5000/rss?token=80dadc72cf602324fd276e496cd91cac

实测输出(片段,含变更条目):

<?xml version='1.0' encoding='UTF-8'?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" ... version="2.0"><channel><title>changedetection.io</title>...
<item><title>http://127.0.0.1:8000/status.json</title><link>http://127.0.0.1:5000/diff/909d2621-04cc-4604-8bef-878e5391d628</link>
<description><![CDATA[<pre>http://127.0.0.1:8000/status.json had a change.

(changed) 99.0
(into) 88.0
</pre>]]></description><guid isPermaLink="false">909d2621-04cc-4604-8bef-878e5391d628/1792204420</guid><category>JSON测试</category>

6.2 RSS 的典型用法

  • 把 feed 添加到 RSS 阅读器,用"阅读"习惯消化监控变化(Settings → RSS 开启 Enable RSS reader mode 后正文直接内嵌差异);
  • category 字段即监控分组名,可在阅读器中按分组过滤;
  • Settings → RSS 页控制条数(Number of changes to show in watch RSS feed)与静音项(Hide muted watches from RSS feed)。

七、浏览器渲染监控进阶

7.1 启用与确认

配置 PLAYWRIGHT_DRIVER_URL=ws://browser-sockpuppet-chrome:3000 指向独立 Chrome 渲染服务(sockpuppetbrowser)后,服务日志出现(实测原文):

2026-10-17 02:48:55.410 | DEBUG    | changedetectionio.content_fetchers:<module>:184 - Using Playwright library as fetcher

未配置渲染服务时日志为 Falling back to selenium as fetcher(纯 HTTP 模式)——用这一行日志即可判断渲染后端是否就绪。

7.2 双后端对比实测(JS 渲染页)

同一 JS 动态页分别用两种后端监控(创建方式见 Compose 指南 5.1 节),快照对比实测结果:

== html_requests(纯 HTTP 客户端) 最新快照 ==
Dynamic Render Monitor

== html_webdriver(Playwright/Chrome) 最新快照 ==
Dynamic Render Monitor

  JS-RENDERED-2026

JavaScript 写入的 JS-RENDERED-2026 只有 Chrome 渲染后端能抓到。选型结论:静态内容用 html_requests 省资源;任何"浏览器里才看得到"的内容(JS 渲染、登录后内容)必须 html_webdriver。

7.3 渲染监控的三个实用参数

  • Wait seconds before extracting text:渲染后等待秒数,SPA 页面建议 2~5 秒;
  • Execute JavaScript before change detection:抓取前注入执行的 JS(可用于滚动加载、关闭弹窗、点击展开);
  • 视觉差异(image_ssim 处理器):对渲染后页面做截图像素级对比,适合"布局/样式变化"场景,监控编辑页 Processor 可切换。

八、备份与恢复

8.1 内置备份功能(实测)

Settings → Backups 页提供一键备份(界面路径 /backups/)。用 curl 触发的实测流程(POST 需带页面 CSRF token):

curl -s -b /tmp/cj3 -D /tmp/bkh.txt -o /dev/null -X POST -d "csrf_token=$TOKEN" http://127.0.0.1:5000/backups/request-backup

实测回显:

HTTP/1.1 302 FOUND
Location: /backups/create

302 跳转到 /backups/create 完成生成,产物落在数据目录(实测):

-rw-r--r-- 1 root root 18K Oct 17 02:47 /opt/changedetection/data/changedetection-backup-20261017024756.zip

备份包内容(实测 32 个条目,节选):

changedetection.json
887dd27e-b973-46eb-8634-b82f31ae2c8e/tag.json
909d2621-04cc-4604-8bef-878e5391d628/last-checksum.txt
909d2621-04cc-4604-8bef-878e5391d628/695b1e4ea14a79745f55805749ce85e4.txt

即全局配置 + 各监控/分组配置 + 历史快照,覆盖完整业务数据。

8.2 冷备份(tar 打包数据目录)

停服务保证一致性后打包(注意:以下三条命令依次执行,涉及服务启停):

systemctl stop changedetection
tar czf /opt/changedetection-backup-$(date +%Y%m%d).tar.gz -C /opt/changedetection data/
systemctl start changedetection

实测产物:

-rw-r--r-- 1 root root 19K Oct 17 02:39 /opt/changedetection-backup-20261017.tar.gz

8.3 恢复演练(实测全过程)

模拟故障:删除表格监控(API DELETE,204),确认仅剩 4 个监控。然后执行恢复——清空数据目录,从冷备解包,重启:

systemctl stop changedetection
rm -rf /opt/changedetection/data && mkdir -p /opt/changedetection/data
tar xzf /opt/changedetection-backup-20261017.tar.gz -C /opt/changedetection/
systemctl start changedetection

服务启动后验证恢复结果:

curl -s -H "x-api-key: 5521439027a85d13458e92c9c11b0cda" http://127.0.0.1:5000/api/v1/watch | python3 -c "import json,sys; d=json.load(sys.stdin); print('恢复后 watch 数:', len(d)); print('URLs:', [w['url'] for w in d.values()])"

实测回显:

恢复后 watch 数: 5
URLs: ['http://127.0.0.1:8000/status.json', 'http://127.0.0.1:8000/monitor-test.html', 'http://127.0.0.1:8000/table.html', 'https://changedetection.io/CHANGELOG.txt', 'https://news.ycombinator.com/']

被删除的监控完整找回(含配置与历史快照)。注意 API key 也随备份还原(changedetection.json 内),恢复后无需重新配置。

九、升级与回滚

9.1 pip 方式升级(实测 0.55.8 → 0.60.9)

/opt/changedetection/venv/bin/pip show changedetection.io | grep -E "^Version"

实测回显(升级前):

Version: 0.55.8
/opt/changedetection/venv/bin/pip install --upgrade changedetection.io

实测回显(节选):

Successfully installed ... changedetection.io-0.60.9 ...
systemctl restart changedetection
systemctl is-active changedetection && curl -s -o /dev/null -w "HTTP=%{http_code}\n" http://127.0.0.1:5000/

实测回显:

active
HTTP=200

数据结构在首次启动时自动迁移(首启日志 Marking fresh install to schema version 33 即 schema 初始化;老数据升级时同样自动执行 schema 迁移)。

9.2 升级前必做

  1. 备份(第八节任选一种);
  2. 记录当前版本:pip show changedetection.io | grep Version;
  3. 查看目标版本 Release Notes(https://github.com/dgtlmoon/changedetection.io/releases),确认无破坏性变更。

9.3 回滚

pip 方式锁版本重装:

/opt/changedetection/venv/bin/pip install changedetection.io==0.55.8
systemctl restart changedetection

⚠️ 注意:schema 向下不兼容——新版运行过的数据目录直接回滚旧版可能无法启动。回滚的正确姿势:恢复升级前的数据目录备份(8.2 节反向操作),再装旧版。

十、日常巡检与故障排查

10.1 每日巡检清单

systemctl is-active changedetection

实测回显:

active

统计近 24 小时错误/警告日志条数:

journalctl -u changedetection --since "24 hours ago" | grep -cE "ERROR|WARNING"

实测回显:

41

全量入队重检(巡检收尾,确认所有监控可正常抓取):

curl -s -H "x-api-key: 5521439027a85d13458e92c9c11b0cda" "http://127.0.0.1:5000/api/v1/watch?recheck_all=true"

实测回显:

{"status": "OK, queued 5 watches for rechecking"}

关注三点:服务存活、近 24 小时错误/警告量、全量重检后无 last_error 的监控占比(可用 4.7 节脚本定期跑)。

10.2 常见错误速查表(实测原文)

报错/现象原因处理
Exception: Fetch blocked: 'http://...' resolves to a private/reserved IP address or contains a parser-differential payload. Set ALLOW_IANA_RESTRICTED_ADDRESSES=true to allow.监控目标在内网/保留网段systemd 加 Environment=ALLOW_IANA_RESTRICTED_ADDRESSES=true(或 Compose environment)后重启
{"message": "The method is not allowed for the requested URL."} + HTTP 405对 API 用了 PATCH 等不支持的方法修改配置用 PUT;触发重检用 GET ?recheck=true
"Invalid access - API key invalid." + HTTP 403未带/带错 x-api-key到 Settings → API 页核对 token
直接 cat 快照文件显示乱码快照文件含编码处理,不适合直接读统一走 GET /api/v1/watch/<uuid>/history/<ts> 读取
日志出现 Unable to set locale ('en_US', 'UTF-8') for category 0, locale is not installed maybe?系统未生成 en_US.UTF-8 locale不影响功能;消除:apt-get install -y locales && locale-gen en_US.UTF-8
通知不送达渠道配置/网络/静音先用测试发送按钮;查日志中 Apprise 报错;确认未 mute

10.3 磁盘与性能维护

  • 历史快照增长控制:General 页限制每监控历史条数 + 启动参数 -c 清理无引用快照;
  • worker 调优:FETCH_WORKERS(默认 10)按 CPU/带宽调整;浏览器渲染监控的内存开销远高于纯 HTTP,量大时分批启用;
  • 日志治理:LOGGER_LEVEL=INFO 或 -l INFO。

十一、参考链接