尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

用Python搭建公开信息变更监控系统,第一时间发现平台悄悄改版

用Python搭建公开信息变更监控系统,第一时间发现平台悄悄改版 这次我们不看开源模型先从一个很真实的吐槽切入大量网约车司机在群里交流时才意识到滴滴又改版了而且平台没有提前发通知。有人直接用了“偷摸改版”这个词。其实不只是网约车平台几乎所有依赖规则吃饭的行业都在经历同样的问题——你天天在用的 App、后台系统、规则文档随时可能被默默更新等业务已经受影响才反应过来。这类问题的技术本质是信息差你有一个依赖的信息源但信息源本身不会主动告诉你“我变了”。网约车司机关注计价规则、接单展示逻辑、司机端页面入口运营人员关注后台公告、审核规范、活动入口自由职业者更惨一个按钮的位置变化就可能打断整套工作流。大部分人的应对方式是在群里等着别人喊一嗓子或者等账号被限权、收入受影响之后再去查原因。这篇文章不打算讲“怎么破解”或“怎么绕过”而是给出一套通用的公开信息变更监控方案。核心思路是不碰非公开数据、不去逆向 App、不登录后台只盯应用商店页面、官方帮助中心、服务协议、规则公告等公开页面。内容包含完整的 Python 实现、通知推送、定时任务配置、监控目标设计、排错清单和合规边界适合有 Python 基础、想把日常信息监控自动化的读者。先看一张核心能力速览表。1. 公开信息变更监控系统能力速览能力项说明适用对象网约车司机、外卖骑手、电商运营、自媒体运营、依赖平台工具的个人开发者监控范围应用商店介绍页、官方帮助中心、服务协议、规则公告、FAQ 页面实现语言Python 3.8 以上依赖库requests、beautifulsoup4可选 lxml数据存储JSON 文件保存历史哈希无需数据库通知方式Server酱、钉钉机器人、企业微信机器人、邮件定时方案Linux crontab、Windows 任务计划、腾讯云/阿里云函数定时触发器硬件要求任意能跑 Python 的机器树莓派、旧笔记本、云服务器均可API 能力无额外 API纯脚本自用批量任务支持多目标配置循环比对成本依赖机器可忽略不计云函数免费额度足够合规边界只采集公开页面不绕过登录、验证码、风控机制这套方案的关键价值不在“抓取”而在“持续比对”。你要是手动打开十几个网页逐个看一两天还能坚持一个月后就放弃了。自动化脚本每天定时跑页面发生变化才推送一次其他时间保持静默。2. 为什么平台改版很难第一时间知道先说平台为什么不主动通知。从产品迭代的视角看主流互联网公司普遍采用灰度发布和静默升级策略先让一小部分用户看到新版观察数据和崩溃率再逐步放量。这样做是为了控制风险但同时也意味着大多数用户并不会在改版前收到通知。还有一个现实因素很多改版根本不是“前端界面变化”而是“后端规则变化”。页面看起来没变但计价模型、派单权重、审核标准已经被服务端悄悄调整了。这种调整用户无法从 App 更新日志里看到只能通过实际体验去反推。对依赖平台规则工作的人来说这个问题会被放大网约车司机计价规则更新、热区展示调整、司机端报名入口变化。外卖骑手配送费计算规则、活动任务入口、奖惩规则变更。电商运营平台流量规则、搜索排序逻辑、活动报名入口调整。内容创作者推荐机制、分成规则、功能入口迁移。这些变化往往没有官方主动推送。即使推送也可能因为消息折叠、通知关闭、无人关注而被错过。比较可靠的做法是主动建立一个信息源监控体系把“平台改版”变成“定时扫描 差异比对 通知推送”。这里要明确边界不是让你去抓非公开数据。公开页面本身就包含了大量变化信号。应用商店的版本描述、官方帮助中心的新增条目、服务协议里的条款变化这些都不需要任何突破手段但绝大多数人不会天天盯着看。自动化监控解决的正是这个问题。3. 三条成熟的公开监控思路对比在写代码之前先看三条最常用的技术路线。不同路线对应不同的变化类型可以单独用也可以组合用。监控思路监控对象能发现什么实现成本局限性应用商店版本信息监控应用商店页面的版本号、更新描述、包名App 发布新版本、更新说明变化低直接请求公开 HTML只能看到前端版本看不到服务端规则网页内容哈希监控帮助中心、规则页面、协议页面的可见文本新增规则、修改条款、FAQ 更新低BeautifulSoup 提取文本后做哈希页面结构变化会导致误报需要定期调整选择器接口返回变化监控公开接口的 JSON 返回服务端规则变化导致的字段调整中需要分析接口接口地址可能变化需维护从实用角度看网页内容哈希监控是最通用的方案。它不针对某个平台写死逻辑而是把任意公开页面当作比较对象。你只需要告诉脚本三个信息页面地址、提取规则、关键词过滤条件。剩下的工作就是定时跑、比对、推送。对于网约车场景建议组合应用商店监控和帮助中心监控。应用商店版本信息能告诉你 App 是否更新了帮助中心和服务协议能告诉你具体改了什么规则。两个信息源互相补充基本可以覆盖大部分“偷摸改版”的场景。4. 监控系统设计这套系统的设计目标是简单、可维护、不引入重型依赖。整体架构如下targets.json - monitor.py - state.json - notify.py - 手机/群消息targets.json监控目标配置一个页面一条记录。monitor.py主脚本负责抓取、解析、哈希、比对。state.json历史状态文件保存每个目标的哈希值和抓取时间。notify.py推送模块把变化信息发到 Server酱、钉钉或企业微信。目录结构建议这样组织change-monitor/ ├── monitor.py ├── notify.py ├── targets.json ├── state.json ├── requirements.txt └── logs/monitor.py不直接写死监控地址而是从targets.json读取配置。新增监控目标只需要改 JSON 文件不需要动代码。这样后续给不同平台加监控非常方便。5. 核心实现代码先安装依赖。pip install requests beautifulsoup4 lxmlrequirements.txt内容如下requests2.28.0 beautifulsoup44.11.0 lxml4.9.0这是targets.json的配置示例。每个目标包含名称、URL、内容提取方式和关键词过滤规则。{ targets: [ { name: 滴滴司机端帮助中心, url: https://example.com/driver/help, selector: div.content, type: text, keywords: [计价, 规则, 奖励, 口碑] }, { name: 应用商店版本页, url: https://example.com/app/driver, selector: div.update-info, type: text, keywords: [版本, 更新, 新增, 优化] } ], request_headers: { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 } }注意配置文件里的 URL 用的是example.com实际部署时要替换成你要监控的真实公开页面地址。不要填需要登录或验证的地址这类页面不在本方案支持范围内。接下来是主脚本monitor.py。import hashlib import json import re from pathlib import Path import requests from bs4 import BeautifulSoup BASE_DIR Path(__file__).resolve().parent CONFIG_FILE BASE_DIR / targets.json STATE_FILE BASE_DIR / state.json def load_json(path, defaultNone): if not path.exists(): return default if default is not None else {} with open(path, r, encodingutf-8) as f: return json.load(f) def save_json(path, data): with open(path, w, encodingutf-8) as f: json.dump(data, f, ensure_asciiFalse, indent2) def fetch_html(url, headers): response requests.get(url, headersheaders, timeout20) response.raise_for_status() response.encoding response.apparent_encoding return response.text def extract_text(html, selector): soup BeautifulSoup(html, lxml) if selector: node soup.select_one(selector) if node: return node.get_text(\n, stripTrue) return soup.get_text(\n, stripTrue) def normalize_text(text, keywords): text re.sub(r\s, , text) lines [line.strip() for line in text.split(\n) if line.strip()] if not keywords: return lines result [] for line in lines: for kw in keywords: if kw in line: result.append(line) break return result def calc_hash(lines): content json.dumps(lines, ensure_asciiFalse).encode(utf-8) return hashlib.sha256(content).hexdigest() def main(): config load_json(CONFIG_FILE) state load_json(STATE_FILE) targets config.get(targets, []) headers config.get(request_headers, {}) changed [] for target in targets: name target[name] url target[url] selector target.get(selector, ) keywords target.get(keywords, []) try: html fetch_html(url, headers) text extract_text(html, selector) lines normalize_text(text, keywords) current_hash calc_hash(lines) except Exception as e: print(f[ERROR] {name} 抓取失败: {e}) continue old_hash state.get(name, {}).get(hash) if old_hash and old_hash ! current_hash: changed.append({ name: name, url: url, old: state[name].get(hash, ), new: current_hash }) print(f[CHANGED] {name} 页面内容发生变化) state[name] { hash: current_hash, last_check: __import__(datetime).datetime.now().isoformat() } save_json(STATE_FILE, state) if changed: from notify import send_notification send_notification(changed) if __name__ __main__: main()这段代码的逻辑很直接抓取页面、提取关键内容、做哈希、对比历史哈希。第一次运行没有历史记录所以不会推送只保存状态。以后每次运行只有内容真正变化才触发通知。如果页面结构发生变化导致选择器失效脚本会抓到整页文本这时候可能产生误报。解决办法很简单把keywords配置成更精确的关键词减少无关内容的干扰。6. 通知推送实现监控脚本发现变化后需要把消息发到手机。国内最方便的是 Server酱、钉钉机器人和企业微信机器人。下面是三个示例任选一个就够了。6.1 Server酱推送Server酱通过微信服务号发送消息适合个人自用。import requests def send_serverchan(title, content, sendkey): url fhttps://sctapi.ftqq.com/{sendkey}.send payload { title: title, desp: content } resp requests.post(url, datapayload, timeout15) return resp.json()6.2 钉钉机器人推送钉钉群聊里添加自定义机器人后拿到 Webhook 地址即可推送。import requests import time import hmac import hashlib import base64 import urllib.parse def send_dingtalk(webhook, secret, title, content): timestamp str(round(time.time() * 1000)) string_to_sign f{timestamp}\n{secret} hmac_code hmac.new( secret.encode(utf-8), string_to_sign.encode(utf-8), digestmodhashlib.sha256 ).digest() sign urllib.parse.quote_plus(base64.b64encode(hmac_code)) url f{webhook}timestamp{timestamp}sign{sign} payload { msgtype: markdown, markdown: { title: title, text: f## {title}\n\n{content} } } resp requests.post(url, jsonpayload, timeout15) return resp.json()6.3 统一调用入口写一个notify.py里面根据环境变量选择推送渠道。import os def send_notification(changed_items): # 从环境变量读取配置 sendkey os.getenv(SERVERCHAN_SENDKEY, ) dingtalk_webhook os.getenv(DINGTALK_WEBHOOK, ) dingtalk_secret os.getenv(DINGTALK_SECRET, ) if not changed_items: return title f发现 {len(changed_items)} 个页面变化 lines [] for item in changed_items: lines.append(f[{item[name]}]({item[url]})) content \n\n.join(lines) if sendkey: send_serverchan(title, content, sendkey) elif dingtalk_webhook: send_dingtalk(dingtalk_webhook, dingtalk_secret, title, content) else: print(未配置任何通知渠道请设置环境变量)标题里直接显示变化的页面名称和链接。点进去就能看到具体内容不需要回到电脑前。6.4 邮件推送如果不想用第三方推送工具也可以直接用 SMTP 发邮件。Python 标准库smtplib就够了。import smtplib from email.mime.text import MIMEText from email.header import Header def send_email(subject, content, smtp_host, smtp_port, username, password, from_addr, to_addr): msg MIMEText(content, plain, utf-8) msg[Subject] Header(subject, utf-8) msg[From] from_addr msg[To] to_addr with smtplib.SMTP_SSL(smtp_host, smtp_port, timeout20) as server: server.login(username, password) server.sendmail(from_addr, [to_addr], msg.as_string())邮件适合做日汇总推送适合做实时告警。建议两个通道分开用重要变更走钉钉或 Server酱每日汇总走邮件。7. 定时任务配置脚本写好后还需要定期执行。这里给出 Linux 和 Windows 两种常见配置。7.1 Linux crontab每天每隔一小时检查一次日志写入logs/monitor.log。0 * * * * cd /opt/change-monitor /usr/bin/python3 monitor.py logs/monitor.log 21如果不想每小时刷太多次也可以改成每天三次0 */8 * * * cd /opt/change-monitor /usr/bin/python3 monitor.py logs/monitor.log 217.2 Windows 任务计划在 Windows 上可以写一个run.batecho off cd /d D:\change-monitor python monitor.py logs\monitor.log 21然后在“任务计划程序”里创建基本任务触发器选择“每天”操作选择“启动程序”程序指向run.bat。如果机器不关机建议把触发时间设在白天整点。7.3 云函数定时触发如果本地不想一直开着机器可以改用云函数。腾讯云和阿里云都有一定免费额度。把monitor.py和notify.py上传到云函数设置一个定时触发器每 4 小时跑一次。这样不依赖本机睡眠和断电稳定性会高很多。8. 监控目标怎么设计有读者可能会问滴滴司机端页面我没权限看怎么监控这里要区分清楚你的目标是“公开信息”不是“App 内部页面”。实际上平台改版会留下大量公开痕迹监控目标监控内容能发现什么应用商店司机端页面版本号、更新说明App 是否发布新版本、更新描述关键词网约车平台帮助中心司机常见问题、计价说明规则调整、新功能上线服务协议/隐私政策条款文本计费规则、分成比例等重大变更官方公告/新闻页公告标题与正文规则、活动、政策调整乘客端介绍页活动文案、服务说明平台运营方向变化具体到配置监控帮助中心时建议把关键词设置成和你最相关的业务词。比如司机重点关注“计价”“抽成”“口碑值”“顺风车”“奖励”运营重点关注“审核”“保证金”“提现”“活动”。这样即使页面里有很多噪音内容也能把与自身相关的变更筛出来。9. 常见问题与排查方法问题现象可能原因排查方式解决方案脚本运行无输出且不推送页面未变化或选择器不匹配先手动抓一次页面确认文本为空调整 selector改成能取到正文的节点页面结构变化导致误报网站改版了 HTML 结构检查选择器是否还在更新 targets.json 中的 selector 和 keywords中文乱码页面编码判断错误查看页面原始响应头手动指定 encoding例如response.encoding utf-8提示 403/429请求过于频繁被限制检查日志中的状态码降低频率设置请求头必要时加延时第一次运行就推送变化没有历史状态查看 state.json 是否存在正常现象之后不会再推明明页面变了但不推送关键词过滤把内容滤掉了手动打印 lines 列表放宽关键词或去掉关键词过滤通知内容为空changed_items 结构变化打印 item 内容确认 notify.py 中读取字段名一致服务器无法访问目标页面网络环境限制curl 测试目标地址更换能正常访问的监控地址这里特别提醒一个点不要把监控频率设得太高。每小时一次已经足够频率过高更容易触发反爬和误报。监控的目标是“稳定可持续”不是“秒级发现”。10. 资源占用与性能观察整套系统非常轻量。脚本使用 requests 同步抓取不走浏览器渲染CPU 峰值非常低。实际运行中内存占用通常在 50MB 到 150MB 之间取决于页面响应体大小。如果你用云函数冷启动时间也就几秒免费额度足够跑很久。如果监控目标增加到几十个性能问题才会显现。这时建议做三点优化使用requests.Session()复用连接。将多个目标并发抓取用concurrent.futures.ThreadPoolExecutor控制线程数。对响应体做大小上限判断避免超大页面拖慢内存。具体到验证方式可以先在本地用python monitor.py手动跑一次观察 state.json 是否生成再修改页面内容测试通知是否触发。确认没问题后再挂定时任务。11. 合规与安全边界这套方案完全基于公开信息监控但使用者依然要注意边界只抓取公开可见的页面不采集用户个人信息、不登录账号、不绕过验证码。不监控任何需要授权才能访问的数据包括司机后台、管理后台、内部 API。设置合理的请求频率避免对目标网站造成压力。使用抓取结果时注意著作权和平台条款不批量搬运文案。监控到平台规则变化后以官方公告和实际页面为准不能只看第三方解读。如果你监控的是自己的平台账号、自己的业务页面那完全没问题。如果监控的是第三方平台公开页面也要遵守目标网站的robots.txt和使用条款。技术方案本身是中性的但使用场景必须合法合规。对于网约车司机这类用户更稳妥的建议是把官方帮助中心和应用商店页面作为监控源发现变化后再去 App 内查看正式规则。任何以“提前获取内部规则”为目的的抓取行为都不在本方案支持范围内。12. 总结与下一步回到最开始的问题平台偷摸改版为什么不告诉你因为产品逻辑就是这样。但作为依赖平台生态的人你可以把信息差变成自动化工具。这套公开信息变更监控系统核心逻辑只有三步抓取、比对、通知。不依赖复杂架构不需要数据库一台旧电脑就可以长期跑。建议先做两件事第一把targets.json里配置成你真正关心的 3 到 5 个公开页面先用一条关键词规则跑一天。第二配置好 Server酱或钉钉机器人手动改一次页面文本验证推送链路是否通。链路通了再考虑加多目标和定时任务。最容易踩的坑是 selector 配置不准确导致第一次运行抓不到正文内容所以第一次调试时建议先打印lines输出确认抓到了有效文本再交给脚本自动化去跑。接下来如果想扩展可以考虑把 state.json 换成 SQLite支持更长时间维度的变更历史加入 diff 文本推送消息时直接展示变化前后的关键行把脚本打包成 Docker 镜像部署更干净。平台改版永远都会有工具的价值就是让变化出现在你眼前而不是等损失出现后才知道。
返回列表