在信息爆炸的时代,用户往往需要从多个渠道获取新闻。一个新闻聚合工具 能够帮助我们自动化收集、分类和展示新闻,从而节省时间并提升阅读效率。本文将带你用 Go 语言实现一个简易的新闻聚合器,从多个 RSS 源抓取新闻并展示到网页端。
功能目标
-
数据采集
- 从多个新闻源(RSS/Atom)抓取新闻标题、链接、发布时间。
-
数据聚合
- 将不同来源的新闻合并,按时间排序。
-
数据展示
- 提供一个 Web 页面,列出最新新闻。
-
扩展性
- 可轻松添加新的新闻源。
技术栈
- Go 标准库 :
net/http
、html/template
- RSS/Atom 解析 :mmcdole/gofeed
- 并发采集:goroutine + channel
项目结构
go
news-aggregator/
├── main.go
├── templates/
│ └── index.html
├── go.mod
核心代码(main.go)
go
package main
import (
"html/template"
"log"
"net/http"
"sort"
"time"
"github.com/mmcdole/gofeed"
)
// 新闻结构体
type NewsItem struct {
Title string
Link string
Date time.Time
Source string
}
// 聚合器
type Aggregator struct {
feeds []string
items []NewsItem
}
func NewAggregator(sources []string) *Aggregator {
return &Aggregator{feeds: sources}
}
// 抓取新闻
func (a *Aggregator) Fetch() {
parser := gofeed.NewParser()
var allItems []NewsItem
for _, url := range a.feeds {
feed, err := parser.ParseURL(url)
if err != nil {
log.Println("❌ 获取失败:", url, err)
continue
}
for _, item := range feed.Items {
pub := time.Now()
if item.PublishedParsed != nil {
pub = *item.PublishedParsed
}
allItems = append(allItems, NewsItem{
Title: item.Title,
Link: item.Link,
Date: pub,
Source: feed.Title,
})
}
}
// 按时间排序
sort.Slice(allItems, func(i, j int) bool {
return allItems[i].Date.After(allItems[j].Date)
})
a.items = allItems
}
// 启动 Web 服务
func (a *Aggregator) Serve() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
tpl := template.Must(template.ParseFiles("templates/index.html"))
tpl.Execute(w, a.items)
})
log.Println("✅ 新闻聚合服务启动: http://localhost:8080")
http.ListenAndServe(":8080", nil)
}
func main() {
// 新闻源
sources := []string{
"https://rss.sina.com.cn/news/china/focus15.xml",
"http://feeds.bbci.co.uk/news/rss.xml",
"https://rss.nytimes.com/services/xml/rss/nyt/World.xml",
}
agg := NewAggregator(sources)
// 定时抓取
go func() {
for {
agg.Fetch()
time.Sleep(10 * time.Minute)
}
}()
// 启动 Web 展示
agg.Serve()
}
模板文件(templates/index.html)
html
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>新闻聚合工具</title>
</head>
<body>
<h1>最新新闻</h1>
<ul>
{{range .}}
<li>
<a href="{{.Link}}" target="_blank">{{.Title}}</a>
<small>({{.Source}} - {{.Date.Format "2006-01-02 15:04"}})</small>
</li>
{{end}}
</ul>
</body>
</html>
使用方法
- 初始化项目并安装依赖:
bash
go mod init news-aggregator
go get github.com/mmcdole/gofeed
- 运行:
bash
go run main.go
- 浏览器访问 http://localhost:8080,即可查看最新新闻。
扩展功能
- 搜索功能:支持按关键词过滤新闻
- 分类展示:按来源或主题分组
- 存储与历史记录:将新闻保存到数据库(SQLite/MySQL)
- 推送功能:结合邮件/微信/钉钉推送最新新闻
- 前端美化:结合 Vue/React 优化界面
总结
通过本案例,我们实现了一个简易的新闻聚合工具 :能够从多个 RSS 源抓取新闻,按时间排序,并通过 Web 页面展示。项目中涵盖了HTTP 请求、RSS 解析、定时任务、模板渲染等常见技能,是 Go Web 开发与实用工具开发的良好实践。