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

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


功能目标

  1. 数据采集

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

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

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

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

技术栈

  • Go 标准库net/httphtml/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 开发与实用工具开发的良好实践。

相关推荐
IT_陈寒1 小时前
Python开发者必须掌握的12个高效数据处理技巧,用过都说香!
前端·人工智能·后端
一只叫煤球的猫10 小时前
写代码很6,面试秒变菜鸟?不卖课,面试官视角走心探讨
前端·后端·面试
bobz96510 小时前
tcp/ip 中的多路复用
后端
bobz96510 小时前
tls ingress 简单记录
后端
你的人类朋友11 小时前
什么是OpenSSL
后端·安全·程序员
bobz96512 小时前
mcp 直接操作浏览器
后端
前端小张同学14 小时前
服务器部署 gitlab 占用空间太大怎么办,优化思路。
后端
databook14 小时前
Manim实现闪光轨迹特效
后端·python·动效
武子康15 小时前
大数据-98 Spark 从 DStream 到 Structured Streaming:Spark 实时计算的演进
大数据·后端·spark