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 开发与实用工具开发的良好实践。

相关推荐
一 乐8 小时前
婚纱摄影网站|基于ssm + vue婚纱摄影网站系统(源码+数据库+文档)
前端·javascript·数据库·vue.js·spring boot·后端
码事漫谈9 小时前
Protocol Buffers 编码原理深度解析
后端
码事漫谈9 小时前
gRPC源码剖析:高性能RPC的实现原理与工程实践
后端
踏浪无痕11 小时前
AI 时代架构师如何有效成长?
人工智能·后端·架构
程序员小假11 小时前
我们来说一下无锁队列 Disruptor 的原理
java·后端
武子康12 小时前
大数据-209 深度理解逻辑回归(Logistic Regression)与梯度下降优化算法
大数据·后端·机器学习
maozexijr12 小时前
Rabbit MQ中@Exchange(durable = “true“) 和 @Queue(durable = “true“) 有什么区别
开发语言·后端·ruby
源码获取_wx:Fegn089512 小时前
基于 vue智慧养老院系统
开发语言·前端·javascript·vue.js·spring boot·后端·课程设计
独断万古他化13 小时前
【Spring 核心: IoC&DI】从原理到注解使用、注入方式全攻略
java·后端·spring·java-ee
毕设源码_郑学姐13 小时前
计算机毕业设计springboot基于HTML5的酒店预订管理系统 基于Spring Boot框架的HTML5酒店预订管理平台设计与实现 HTML5与Spring Boot技术驱动的酒店预订管理系统开
spring boot·后端·课程设计