项目地址 GitHub - ourongxing/newsnow: Elegant reading of real-time and hottest news
新闻源扩展准备工作
在开始之前,请确保你已完成以下准备:
- 已克隆项目仓库:
git clone https://gitcode.com/GitHub_Trending/ne/newsnow - 已安装Node.js(>=20版本)和pnpm包管理器
- 具备基础的JSON和JavaScript知识
项目中与新闻源相关的核心文件结构如下:
newsnow/
├── server/sources/ # 数据源抓取逻辑实现
└── shared/
├── sources.json # 新闻源配置信息
└── sources.ts # 新闻源类型定义
主要配置文件说明:
- shared/sources.json:存储所有新闻源的元数据(名称、分类、更新频率等)
- server/sources/:存放各新闻源的具体数据抓取逻辑代码
步骤一:添加新闻源配置
首先需要在sources.json中添加新的新闻源配置。以添加"GitHub Trending"为例,配置格式如下:
"apnews": {
"name": "AP News",
"type": "hottest",
"column": "world",
"home": "https://apnews.com",
"color": "blue",
"interval": 600000
},
关键配置项说明:
name:新闻源名称,将显示在UI界面上column:新闻分类(tech/finance/china/world等)interval:数据抓取间隔(毫秒),建议不小于600000(10分钟)color:UI显示颜色,支持slate/blue/red等预定义值
步骤二:实现数据抓取逻辑
在server/sources目录下创建对应的数据源文件,例如server/sources/github.ts,实现数据抓取逻辑。基本结构如下:
import * as cheerio from "cheerio"
import { myFetch } from "../utils/fetch"
interface APNewsItem {
id: string
title: string
link: string
description?: string
pubDate: string
}
export default defineSource({
apnews: async () => {
const url = "https://apnews.com/hub/ap-top-news"
const html = await myFetch(url)
// 使用cheerio解析HTML
const $ = cheerio.load(html)
const newsItems = []
// 解析AP News的热门新闻列表
$("div.FeedCard").each((_, element) => {
const title = $(element).find("h2[data-key='card-headline']").text().trim()
const link = $(element).find("a[data-key='card-headline']").attr("href")
const description = $(element).find("p[data-key='card-description']").text().trim()
if (title && link) {
const fullLink = link.startsWith("http") ? link : `https://apnews.com${link}`
newsItems.push({
id: fullLink,
title,
url: fullLink,
extra: {
description: description || ""
}
})
}
})
// 如果上面的选择器没有找到内容,尝试备用选择器
if (newsItems.length === 0) {
$("a.Link").each((_, element) => {
const title = $(element).text().trim()
const link = $(element).attr("href")
if (title && link && title.length > 10) {
const fullLink = link.startsWith("http") ? link : `https://apnews.com${link}`
newsItems.push({
id: fullLink,
title,
url: fullLink
})
}
})
}
return newsItems.slice(0, 20)
},
})
核心要点:
- 使用
myFetch函数获取网页内容(如果使用代理需要定义构建函数,然后在个数据源的获取位置调用) - 根据目标网站结构解析数据,提取标题、链接、描述等信息
- 返回符合NewsItem类型的数组
- 通过
defineSource注册数据源
步骤三:测试与验证
完成代码编写后,执行以下命令启动本地开发服务器:
pnpm dev
访问http://localhost:3000,在界面中添加新的新闻源,验证数据是否正常显示。常见问题排查:
- 数据不显示:检查浏览器控制台网络请求,确认API是否返回数据
- 抓取失败:检查目标网站结构是否变化,调整解析逻辑
- 频率限制:适当增大interval值,避免被目标网站封禁IP
高级配置与优化
支持多种内容类型
通过配置type字段支持不同类型的内容:
hottest:热门内容realtime:实时内容latest:最新内容
自定义缓存策略
在数据源配置中添加cache字段自定义缓存策略:
"cache": {
"maxAge": 3600000, // 缓存时长(毫秒)
"staleWhileRevalidate": 600000 // 后台更新时长
}
Docker部署:
- 本地构建
pnpm build
- 上传文件到服务器
需要上传以下文件:
-
`dist/` 目录(整个目录)
-
`docker-compose.yml`
-
`Dockerfile`
- 服务器部署
构建镜像
docker-compose build
启动服务
docker-compose up -d
注意:如果直接替换dist后页面没变,直接构建docker镜像