Go语言实战案例-项目实战篇:新闻聚合工具

在信息爆炸的时代,用户往往需要从多个渠道获取新闻。一个新闻聚合工具 能够帮助我们自动化收集、分类和展示新闻,从而节省时间并提升阅读效率。本文将带你用 Go 语言实现一个简易的新闻聚合器,从多个 RSS 源抓取新闻并展示到网页端。


功能目标

  1. 数据采集

    • 从多个新闻源(RSS/Atom)抓取新闻标题、链接、发布时间。
  2. 数据聚合

    • 将不同来源的新闻合并,按时间排序。
  3. 数据展示

    • 提供一个 Web 页面,列出最新新闻。
  4. 扩展性

    • 可轻松添加新的新闻源。

技术栈

  • 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>

使用方法

  1. 初始化项目并安装依赖:
bash 复制代码
go mod init news-aggregator
go get github.com/mmcdole/gofeed
  1. 运行:
bash 复制代码
go run main.go
  1. 浏览器访问 http://localhost:8080,即可查看最新新闻。

扩展功能

  1. 搜索功能:支持按关键词过滤新闻
  2. 分类展示:按来源或主题分组
  3. 存储与历史记录:将新闻保存到数据库(SQLite/MySQL)
  4. 推送功能:结合邮件/微信/钉钉推送最新新闻
  5. 前端美化:结合 Vue/React 优化界面

总结

通过本案例,我们实现了一个简易的新闻聚合工具 :能够从多个 RSS 源抓取新闻,按时间排序,并通过 Web 页面展示。项目中涵盖了HTTP 请求、RSS 解析、定时任务、模板渲染等常见技能,是 Go Web 开发与实用工具开发的良好实践。

相关推荐
Java爱好狂.4 小时前
Java初学者如何一周速通SpringBoot!
java·spring boot·后端·spring·高并发·架构师·java面试
马良神笔6 小时前
2026 年Rag最近技术前沿总结
后端·python·django
程序猿DD6 小时前
同样10美元,OpenDesign和Command Code的DeepSeek V4.1 Flash额度到底有多少?
后端
高频因子挖掘机6 小时前
A股量化从日线升级到5分钟线:数据量增加后最先暴露哪些工程问题?
后端·github·api
高频因子挖掘机7 小时前
历史行情返回顺序变了,为什么按行号计算指标很危险?
后端·github·api
团子哒哒8 小时前
数组、切片和Map
后端
专注仿真8 小时前
ThinkPHP6 API接口开发实例:从零搭建RESTful风格接口
后端·php·restful
开心猴爷9 小时前
应对iOS审核4.3:可以使用 IpaGuard 来给属性名混淆的技术细节与平衡之道
后端·ios
1m555555559 小时前
RAG 工程实战(五):正确知识已经进入 Prompt,为什么大模型还是会答错?
后端·面试
易小尊9 小时前
我的模型在 65% 以上时准得可怕,在 50% 时像在掷硬币
后端