从零做一个每天准点送达的 AI 资讯摘要机器人
前言
信息过载是每个技术人的日常:AI 圈一天冒出几十条新闻,打开十几个网站逐条翻太浪费时间。我的解决思路是:让服务器替我读新闻,每天早上把精选摘要准时送到我手机上。本文分享这个定时资讯摘要机器人的完整实现,全部跑在一台最低配的云服务器上。
一、整体设计
定时任务(cron,每天 09:00)
│
▼
抓取模块:请求多个资讯源(科技媒体、AI 资讯站)
│
▼
去重与筛选:按关键词、标题相似度过滤
│
▼
格式化:整理为「标题 + 一句话摘要 + 原文链接」
│
▼
推送:编码后通过消息渠道送达手机
设计原则只有一条:宁可少推,不要推水。每天固定 8-12 条精选,比几十条全量转发有用得多。
二、关键实现细节
1. 抓取:别死磕一个源
单一来源挂了整个机器人就哑了,所以我同时抓 3-4 个源,任何一个失败不影响整体:
import requests
SOURCES = ["https://source-a.example/rss", "https://source-b.example/rss"]
def fetch_all():
items = []
for url in SOURCES:
try:
r = requests.get(url, timeout=10)
items += parse_feed(r.text)
except Exception as e:
print(f"source failed: {url}, {e}") # 记日志但继续
return items
经验:RSS 比爬网页稳定得多,优先找有 RSS 的站点;请求一定要加 timeout,否则一个卡死的源能拖垮整个任务。
2. 去重:不要只比较标题字符串
同一件事不同媒体的标题措辞差异很大,我用「标题分词 + 关键词集合相似度」来去重:
def similar(t1, t2):
s1, s2 = set(tokenize(t1)), set(tokenize(t2))
if not s1 or not s2:
return 0
return len(s1 & s2) / len(s1 | s2) # Jaccard 相似度
相似度超过 0.6 视为同一条新闻,保留来源更权威的那条。另外把最近 3 天的标题存成历史文件,避免隔天重复推送。
3. 定时:cron 的三个坑
-
时区:服务器默认是 UTC,
0 1 * * *其实是北京时间 09:00,先timedatectl set-timezone Asia/Shanghai再写 crontab,少走弯路。 -
环境变量:cron 里的 PATH 和你登录 shell 完全不同,脚本里要么用绝对路径,要么在脚本开头自己
export PATH。 -
日志:cron 任务出错是没有提示的,务必重定向输出:
0 9 * * * /opt/digest/run.sh >> /var/log/digest.log 2>&1,并且日志文件要配合 logrotate 切割。
4. 推送:中文摘要编码注意
推送内容包含 emoji 和中文,务必用 UTF-8 编码发送,否则会出现乱码;消息体超长要分段,我按 3000 字符切一刀。
三、稳定性进化史
第一版跑了一周就暴露问题:某天源站改版导致解析失败,机器人推送了空内容。后来加了三层防护:
-
空内容熔断:筛选后条目为 0 时,推送一条「今日抓取异常」而不是静默失败——知道自己坏了,比假装正常重要。
-
抓取结果落盘:每次运行把原始结果存 JSON,出问题时可回溯是抓取坏了还是推送坏了。
-
心跳日志:每天运行成功后 append 一行时间戳,
ls -la一眼就能看出哪天没跑。
结语
这个机器人现在每天早上 9 点准时送来 10 条左右的精选资讯,我的信息焦虑基本痊愈了。整套代码不到 200 行,服务器开销可以忽略。最有价值的经验是:自动化脚本的重点不是"能跑",而是"坏了你能立刻知道"——熔断、日志、心跳,这三样比任何花哨功能都重要。欢迎在评论区交流你的资讯订阅方案
- 点赞
- 收藏
- 关注作者
评论(0)