最轻量可控方案是requests+beautifulsoup定时抓取目标区域文本并哈希比对,再用smtplib发邮件;须过滤动态噪声、拆分异常处理、持久化哈希值并用cron调度。

直接用 requests + BeautifulSoup 定期抓取网页、比对哈希值,再通过 smtplib 发邮件是最轻量且可控的方案;别用 Selenium,除非页面严重依赖 JS 渲染。
怎么判断网页内容真的变了?别只看 HTML 标签结构
很多网页在 <script></script> 或 <meta> 里塞了动态时间戳、随机 token、广告位 ID,导致每次请求 HTML 字符串都不同,但真正关心的内容(比如公告正文、价格、状态字段)其实没变。
实操建议:
- 先用浏览器开发者工具定位目标区域,提取唯一标识的容器,例如
div#notice-content或table.product-pricing - 用
BeautifulSoup.select()提取该节点的.get_text(),再去除空白和换行后计算hashlib.md5().hexdigest() - 避免对整个
response.text做哈希——它包含不可控噪声 - 如果目标是 JSON 接口(如
/api/v1/status),直接解析response.json()后取关键字段做比对,更稳定
邮件发送失败常见原因和绕过方法
本地发邮件最常卡在 SMTP 认证或被拒收,错误信息通常是 SMTPAuthenticationError 或 535 Authentication failed。
仅使用 Python 将 Claw Code 虚拟化框架与 OpenClaw 集成,提供 184 种工具和 200 多条命令,用于安全分析和代码质量...
实操建议:
- 用 Gmail 或 Outlook 的「应用专用密码」替代账户密码(需在账号设置中开启两步验证后生成)
- Gmail SMTP 地址必须是
smtp.gmail.com,端口选587(STARTTLS)而非465(SSL) - 发件人地址必须和登录账号一致,否则多数服务商直接拒信;收件人可任意,但首次发建议先发给自己测试
- 邮件正文用
MIMEText(..., 'plain', 'utf-8'),别漏掉utf-8编码,否则中文变乱码
定时检查不能只靠 while True + sleep,得考虑异常恢复
裸写一个无限循环加 time.sleep(300) 看似简单,但一旦网络超时、解析报错或邮件发送失败,程序就卡死或静默退出,监控彻底失效。
实操建议:
- 把抓取、解析、比对、发信拆成独立函数,每步用
try/except包裹,记录错误到日志文件(哪怕只是print(f"[{datetime.now()}] {e}")) - 每次检查前读取上一次的哈希值(存本地
last_hash.txt),更新后再写入;不要依赖内存变量 - 加入重试机制:对
requests.get()设置timeout=(3, 7)和retries=2(用urllib3.Retry配合requests.adapters.HTTPAdapter) - 如果部署在 Linux 上,优先用
cron调度脚本(如每 10 分钟跑一次),比常驻进程更可靠
真正难的不是“怎么发邮件”,而是确定“什么才算变化”——有些网页改了排版但内容没动,有些只更新了发布时间却没改实质信息。哈希比对前务必人工确认几次抓取结果,再决定过滤哪些元素、是否忽略空格和换行。否则告警会变成噪音。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










