核心思路是定期用requests+beautifulsoup抓取网页关键区域html,清洗后生成sha256哈希比对变化;需避开广告、脚本等动态内容,添加ua头和延时防封,用schedule或apscheduler实现可靠定时轮询,并注意js渲染导致的空内容问题。

用 requests + BeautifulSoup 抓取并比对网页内容
核心思路是定期获取页面 HTML,提取关键区域(比如正文、标题、发布时间),再和上次结果做哈希比对。别直接比整个 HTML——广告位、统计脚本、时间戳会频繁变动,导致误报。
实操建议:
- 用
BeautifulSoup定位稳定容器,例如soup.select("article.post-content")或soup.find(id="main-article"),只提取这部分文本 - 清洗后再生成 SHA256:去掉空白符、注释、script/style 标签,用
re.sub(r"\s+", " ", text.strip())统一空格 - 首次运行时把哈希存到本地文件(如
last_hash.txt),后续读取比对 - 避免被封:加
headers={"User-Agent": "Mozilla/5.0 (X11; Linux x86_64)..."},必要时加time.sleep(5)
用 schedule 或 APScheduler 实现定时轮询
Linux 的 cron 适合简单场景,但 Python 脚本自身需要灵活控制重试、超时、日志级别时,APScheduler 更可靠;如果只是每小时跑一次,schedule 足够轻量。
注意点:
-
schedule不是守护进程,脚本退出任务就停 —— 必须用while True: schedule.run_pending(); time.sleep(1)保持运行 -
APScheduler的BackgroundScheduler可以启动后不阻塞主线程,适合集成到更大程序中 - 别用
time.sleep(3600)手写循环:系统时间调整、睡眠被信号中断都会导致错失检查点
处理反爬与动态渲染(遇到 403 或空内容时)
很多网站返回的 HTML 不含真实内容,而是由 JS 渲染的 —— 这时 requests 拿到的是骨架页,BeautifulSoup 解析不出你要的数据。
判断依据:
- 响应状态是
200,但len(response.text)异常小(div id="app" /data-server-rendered - 手动用浏览器禁用 JS 后打开页面,内容消失 → 确认依赖 JS 渲染
应对方式:
- 优先尝试加 Referer、Cookie(从浏览器开发者工具复制)、甚至复用登录态 session
- 真要渲染 JS,用
playwright(比 Selenium 轻、支持无头 Chromium):启动开销大,别每分钟跑一次;设置timeout=10000防卡死 - 有些网站提供 RSS 或官方 API(如 GitHub Pages 的
/atom.xml),优先走这个路径,省去解析烦恼
保存历史快照与通知逻辑怎么设计才不丢更新
只存哈希容易丢失“中间态”——比如页面先更新 A,你没来得及抓,又更新成 B,最终只看到 A→B,漏掉 A。
更稳妥的做法:
- 每次成功抓取后,把精简后的 HTML 片段(带时间戳)追加写入
archive/2024-06-15T14:22:00.html,用目录结构代替数据库 - 通知前先查最近 3 次哈希:如果连续两次相同,第三次不同,才视为有效更新(过滤抖动)
- 发微信/邮件通知时,附上 diff 链接(可用
diff-match-patch库生成简易文本差异),别只写“有更新” - 所有 I/O 操作加
try/except OSError,磁盘满或权限不足时记录错误但不停止主循环
真正难的不是第一次跑通,而是让脚本在后台连跑两周不因网络波动、目标页改版、临时重定向而静默失败。记得在日志里埋好 print(f"[{datetime.now()}] Fetched {url}, status={r.status_code}") 这类可追溯标记。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











