用 http.client 自定义超时和 user-agent,提取目标区域文本并标准化后存哈希比对,用 net/smtp 配 tls 认证发邮件,定时轮询用 time.ticker 并加熔断。

用 http.Get 抓网页内容时,别忘了设置超时和 User-Agent
直接调 http.Get 很容易被目标网站拒绝或卡死,尤其是监控类长期运行的程序。默认没有超时,一次失败可能阻塞整个 goroutine;多数网站还会根据 User-Agent 拒绝空值或爬虫标识过强的请求。
- 必须用
http.Client自定义超时:Timeout: 10 * time.Second是较稳妥的起点,太短易误报,太长拖慢轮询节奏 - 加
Header.Set("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) ..."),否则部分站点返回 403 或空响应 - 注意重定向:默认
http.Client会自动跟随,但有些页面靠 JS 跳转,抓到的可能是跳转前的 HTML,得结合CheckRedirect控制或改用 headless 方案
比对网页变更不能只看完整 HTML 字符串
网页里常有动态插入的时间戳、埋点 script、随机 class 名,全量比对会导致“明明没变却总报警”。关键不是“内容是否一模一样”,而是“业务关心的那块文本有没有动”。
- 优先提取目标区域:用
goquery的Find(".article-title").Text()或正则regexp.MustCompile(`<h1>]*>(.*?)</h1>`)提取稳定结构 - 存储比对基准时,记得做标准化:去除首尾空白、合并连续空白符(
strings.Join(strings.Fields(text), " "))、忽略大小写(如标题不区分 case) - 避免存原始 HTML——体积大、diff 效率低、易受无关变动干扰;存哈希(
sha256.Sum256([]byte(cleanText)).String())更轻量可靠
发邮件用 net/smtp 就够了,但 TLS 和认证细节容易漏
不用引入 heavy 的第三方邮件库,标准库 net/smtp 完全能胜任。问题多出在 TLS 配置和账号权限上,尤其国内邮箱服务商对非官方客户端限制严格。
- Gmail 需开启“App Password”,不能直接用登录密码;QQ 邮箱要开 SMTP 服务并生成独立密码
- 务必用
smtp.PlainAuth+tls.Config{InsecureSkipVerify: false},别设InsecureSkipVerify: true—— 多数企业 SMTP 服务不接受不验证证书的连接 - 发件人地址必须和认证账号一致,否则网易/163 会静默丢弃;收件人列表用逗号分隔字符串,不是切片
定时轮询别用 time.Sleep 硬等,用 time.Ticker 加错误熔断
简单 for + sleep 在出错时会累积延迟,比如某次请求超时 10 秒,下次就晚 10 秒执行,久而久之监控就脱节了。而且没异常隔离,一个 panic 能让整个监控停摆。
立即学习“go语言免费学习笔记(深入)”;
- 用
ticker := time.NewTicker(5 * time.Minute),每次触发检查,不依赖上一次耗时 - HTTP 请求、HTML 解析、邮件发送都包在
defer func() { if r := recover(); r != nil { log.Println("panic:", r) } }()里,防止单次失败崩掉进程 - 连续 3 次获取失败后暂停 1 小时(用
time.AfterFunc重置 ticker),避免无效请求刷屏日志
真正难的不是写通流程,是让程序在没人盯着的时候,既不狂轰滥炸,也不悄无声息地躺平——超时、重试、降级、可观测性,这些才决定它能不能活过第一个周末。










