Golang RSS抓取工具需正确解析XML结构、并发控制与错误恢复;用encoding/xml映射字段,channel+WaitGroup限并发,gofeed库提升兼容性,拆分fetch/parse/store逻辑并防重复入库。

用 Golang 做 RSS 抓取工具,核心是把远程 RSS 源(XML 格式)拉下来、正确解析出标题、链接、发布时间等字段,再按需存储或展示。整个流程不难,但容易在 XML 结构适配、并发控制和错误恢复上出问题。
RSS 是 XML,结构体得对得上
RSS 本质是带层级的 XML 文档,比如 。Go 的 encoding/xml 能直接反序列化,但前提是结构体字段必须:
- 首字母大写(导出字段),否则解析时会被忽略
- 用
xml:"tag_name"标签精准映射 XML 元素名,比如Title string `xml:"title"` - 嵌套结构要逐层定义,
Channel里包一个Items []Item,且Items字段也要加xml:"item" - 时间字段常含时区或格式不一,建议先存原始字符串,后续用
time.Parse转换,别强求xml.Unmarshal直接转成time.Time
别一个一个抓,用 goroutine 并发调度
几十个 RSS 源串行请求太慢,也容易被限流。推荐用 channel + WaitGroup 控制并发量:
- 把所有源 URL 塞进一个
chan string - 启动固定数量 worker(比如 5–10 个),每个从 channel 取 URL 并发起
http.Get - 设置超时:
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second),避免卡死 - 部分网站检查
User-Agent,记得在 request header 里加上,否则返回 403
解析失败很常见,得有重试和兜底
真实 RSS 源质量参差不齐:有的字段缺失、有的 XML 不规范、有的返回 5xx 或空响应。不能一错就退出:
立即学习“go语言免费学习笔记(深入)”;
- 对每个请求做 2–3 次指数退避重试(如 1s、2s、4s 后重试)
- 用
gofeed库可省去手写结构体,它内置兼容多种 RSS/Atom 变体,还支持PublishedParsed时间自动解析 - 遇到解析失败,至少记录日志并跳过,别让单个坏源阻塞整批任务
- 可先用
io.Copy(ioutil.Discard, resp.Body)清理未读 body,防止连接复用异常
数据落地要防重复,别堆在一个函数里
抓完不存等于白干,但直接往数据库狂插容易重复入库:
- SQLite 最轻量,建表时对
link或title + pub_date加唯一索引,插入失败就忽略 - 文件存储适合调试:用
json.MarshalIndent写 JSON,或用csv.Writer输出表格 - 务必把“抓取”“解析”“存储”拆成独立函数或接口(如
Fetcher、Parser、Storer),后续加缓存、加 Web API 都方便 - 如果要做定时更新,用
time.Ticker触发Fetch(),别用time.Sleep阻塞主 goroutine










