Skip to content

kylefu8/openclaw-news-digest

Repository files navigation

openclaw-news-digest

多源新闻聚合引擎:18 个源 → 三级去重 → 配额排序 → LLM 解读 → 定时推送。

基于 OpenClaw 运行,支持飞书、Telegram、Discord、Slack 等多渠道推送。

灵感来源于 LearnPrompt/ai-news-radar,在其基础上重新设计了架构。

特性

  • 18 个新闻源:覆盖 AI/科技、国内时政、国际大事、财经政策、社交热搜
  • 三级去重:L1 URL 归一化 → L2 标题相似度(trigram Jaccard 预过滤 + SequenceMatcher)→ L3 事件聚类
  • 配额制推送:权威媒体优先(Tier 1),AI 垂直补充(Tier 2),热搜/滚动填满(Tier 3)
  • 双管线
    • 快讯速览(12 源):每天 6 次,Top 10 + LLM 读原文生成解读
    • 📖 深度精选(6 源):每天 1 次,精选 3-8 条 + 核心观点 + 推荐理由
  • 并发抓取:ThreadPoolExecutor,12 源 ~3 秒
  • Circuit Breaker:连续 5 次失败自动熔断 1 小时,冷却后自动恢复
  • 原子写 state:tmp + rename,防止写入中断导致数据丢失
  • 推送日志:JSONL 格式记录每次推送的去重/过滤决策
  • 纯 Python,零外部服务依赖:不需要数据库、Redis 或 API key

架构

18个源 → collect.py(并发抓取 → L1/L2 去重 → L3 聚类 → 配额排序)
                              ↓
                     data/latest_fast.json
                              ↓
                  OpenClaw Cron (isolated session)
                              ↓
                     LLM 读原文 → 生成解读
                              ↓
                     message tool → 飞书/Telegram/...

源列表

快讯源(12 个)

类型 Tier 说明
权威时政 澎湃新闻 1 HTML scrape
权威时政 BBC中文 1 HTML scrape
权威时政 联合早报 1 HTML scrape
权威时政 新华社 1 Homepage scrape
权威财经 第一财经 1 HTML scrape
权威财经 界面新闻 1 HTML scrape
财经快讯 财联社电报 1 RSS
国际快讯 BBC Breaking 1 RSS
AI 垂直 36kr AI 2 HTML scrape
热搜/滚动 头条热榜 3 JSON API
热搜/滚动 新浪滚动 3 JSON API
社交热搜 微博热搜 3 Ajax API

深度源(6 个)

类型 说明
AI 深度 数字生命卡兹克 搜狐号 JSON API
AI 深度 量子位 搜狐号 JSON API
自媒体 刘润 搜狐号 JSON API
AI 官方 OpenAI Blog RSS
AI 官方 HuggingFace Blog RSS
国际财经 FT中文网 RSS

快速开始

前置条件

  • Python 3.11+
  • OpenClaw(用于 LLM 解读 + 定时推送)

1. 安装

git clone https://github.com/kylefu8/openclaw-news-digest.git
cd openclaw-news-digest
bash setup.sh

2. 验证抓取

source .venv/bin/activate

# 快讯源 Top 5
python collect.py --flow fast --max-items 5 --format text

# 深度源
python collect.py --flow deep --format text

# JSON 输出(cron job 使用此格式)
python collect.py --flow fast --format json --output data/latest_fast.json --state-dir data --mark-pushed

3. 让 OpenClaw 帮你配置(推荐)

这个项目本身就是为 OpenClaw 设计的。最简单的方式是直接告诉你的 OpenClaw 助手:

我 clone 了 openclaw-news-digest 项目到 ~/openclaw-news-digest,帮我装一下。

OpenClaw 会自动读取 SETUP_GUIDE.md,按步骤完成安装、验证抓取、创建 cron job 并配置推送目标。

你也可以让它帮你定制:

OpenClaw 会直接修改 config.yaml 和 cron job 配置,不需要你手动编辑文件。

3b. 手动配置(不使用 OpenClaw 对话)

cron_templates/ 目录下有两个 cron job 模板:

  1. 编辑模板,替换占位符:

    • {{WORKSPACE}} → 项目绝对路径(如 /home/user/openclaw-news-digest
    • {{CHANNEL}} → 推送渠道(feishu / telegram / discord / slack
    • {{TARGET}} → 推送目标(如 user:ou_xxxchat:xxx
  2. 通过 OpenClaw 导入:

    openclaw cron add --file cron_templates/fast_news.json
    openclaw cron add --file cron_templates/deep_digest.json

定制化

所有配置集中在 config.yaml,无需改代码。

添加/删除新闻源

# config.yaml → sources 下添加
sources:
  my_new_source:
    name: 我的新源
    type: scraper          # scraper / rss / sohu_api / json_api
    module: fetchers.cn_media
    func: fetch_my_source  # 对应 Python 函数名
    flow: fast             # fast(快讯)/ deep(深度)
    tier: 2                # 1=优先 2=补充 3=填满

四种源类型:

  • scraper:HTML 页面解析,需要写对应的 fetch 函数
  • rss:RSS/Atom 订阅,只需填 feed_url(+ 可选 fallback_urls
  • sohu_api:搜狐号 JSON API,只需填 author_id
  • json_api:头条/新浪等 JSON 接口,需要写对应的 fetch 函数

最简方式——添加 RSS 源(零代码):

  my_rss_source:
    name: 某某博客
    type: rss
    module: fetchers.rss
    func: fetch_rss
    flow: deep
    feed_url: https://example.com/feed.xml
    fallback_urls:            # 可选:主 URL 失败时的备用
      - https://mirror.example.com/feed.xml

添加搜狐号(零代码):

  mp_someone:
    name: 某搜狐号
    type: sohu_api
    module: fetchers.sohu
    func: fetch_sohu_author
    flow: deep
    author_id: "123456"      # 搜狐号作者 ID

添加自定义 scraper:

  1. fetchers/ 中写函数,签名 def fetch_xxx(session, *, site_id, site_name, timeout) -> list[NewsItem]
  2. 在 config.yaml 中注册

删除源:直接删掉对应的 yaml 条目即可。

调整配额

quota:
  fast:
    max_items: 10            # 每轮推送条数(改为 15 就推 15 条)
    tiers:
      1: { max: 7, label: "权威媒体" }    # Tier 1 最多占 7 条
      2: { max: 3, label: "AI垂直" }      # Tier 2 最多占 3 条
      3: { fill: true, label: "热搜/滚动" } # Tier 3 补满剩余
  deep:
    max_items: 20            # 深度候选池大小(LLM 从中精选 3-8 条)

调整去重阈值

dedup:
  l2_title_similarity: 0.7   # 标题相似度阈值(调低=更激进去重)
  l2_max_items: 500           # L2 安全阀(防止 O(n²) 过慢)
  l3_cluster_similarity: 0.55 # 事件聚类阈值(调低=更多新闻被合并)
  l2_priority_sources:        # 去重冲突时优先保留这些源
    - xinhua
    - thepaper
    - bbc_cn

调整抓取参数

fetch:
  timeout_connect: 15        # 连接超时(秒)
  timeout_read: 45           # 读取超时(秒)
  socket_timeout: 60         # Socket 超时(秒)
  user_agent: "Mozilla/5.0 ..."  # 自定义 UA

调整推送状态

state:
  ttl_days: 7                # 推送记录保留天数(超期自动清理,避免 state 文件膨胀)

文章时效过滤

通过 --max-age 参数控制只推送最近 N 天的文章,防止 RSS 源或 API 返回过旧内容:

# 快讯:只要最近 2 天(快讯源几乎都是当天内容,2 天防跨午夜丢失)
python collect.py --flow fast --max-age 2

# 深度:最近 7 天(博客/长文更新频率低,7 天覆盖一周精华)
python collect.py --flow deep --max-age 7

推荐值:快讯 --max-age 2,深度 --max-age 7

调整推送时间

push:
  fast:
    schedule: "0 7,10,12,15,18,21 * * *"  # cron 表达式
    timezone: Asia/Shanghai
  deep:
    schedule: "0 20 * * *"
    timezone: Asia/Shanghai

修改后需同步更新 OpenClaw cron job 的 schedule(config.yaml 中的 push 配置仅作参考记录,实际调度由 OpenClaw cron 控制)。

突发事件检测

# 检查是否有 ≥4 家媒体同时报道的事件
python collect.py --flow fast --check-breaking --breaking-threshold 4

可集成到 OpenClaw heartbeat 中,实现突发事件即时推送。

修改排序公式

编辑 ranking.py 中的 score_item() 函数:

# 当前公式
score = multi_source_count * 3 + tier_weight * 2 + freshness

Circuit Breaker 参数

编辑 health.py 中的常量:

CB_THRESHOLD = 5     # 连续失败次数触发熔断
CB_COOLDOWN = 3600   # 熔断冷却时间(秒,默认 1 小时)

CLI 参数

python collect.py [OPTIONS]

Options:
  --flow {fast,deep}      选择管线(默认:全部)
  --format {text,json}    输出格式(默认:text)
  --max-items N           最大输出条数
  --max-age N             只保留最近 N 天的文章(0=不限,推荐:快讯 2,深度 7)
  --output PATH           JSON 输出文件路径
  --state-dir DIR         状态文件目录(用于去重已推送内容)
  --mark-pushed           标记输出的条目为已推送
  --check-breaking        检查是否有突发事件(multi_source ≥ 4)
  --breaking-threshold N  突发事件阈值(默认 4)
  -v, --verbose           Debug 日志

三级去重

层级 方法 阈值 说明
L1 URL 归一化 精确匹配 去 tracking 参数、统一协议
L2 标题相似度 >0.7 trigram Jaccard 预过滤(减少 99.97% 的 SequenceMatcher 调用)
L3 事件聚类 >0.55 UnionFind 聚类,合并同一事件的不同报道

冲突时优先保留 Tier 值更小(更权威)的源。

配额制

层级 说明 默认上限
Tier 1 权威媒体 7 条
Tier 2 AI 垂直 3 条
Tier 3 热搜/滚动 补满至 10

importance 排序公式:multi_source_count × 3 + tier_weight × 2 + freshness

项目结构

openclaw-news-digest/
├── config.yaml           # 源/配额/去重/调度 集中配置
├── setup.sh              # 一键安装脚本
├── pyproject.toml         # 依赖声明 + 工具配置
├── requirements.txt       # pip 依赖
├── collect.py             # 主入口:抓取 → 去重 → 排序 → 输出
├── dedup.py               # 三级去重(L1 URL + L2 标题 + L3 聚类)
├── ranking.py             # importance 评分 + 配额分配
├── health.py              # 源健康追踪 + Circuit Breaker
├── state.py               # 推送状态管理(原子写)
├── push_log.py            # 推送日志(JSONL)
├── fetchers/
│   ├── __init__.py
│   ├── common.py          # NewsItem 数据结构 + 工具函数
│   ├── cn_media.py        # 中文媒体抓取器(12 个函数)
│   ├── rss.py             # 通用 RSS/Atom 解析
│   └── sohu.py            # 搜狐号 JSON API
├── cron_templates/        # OpenClaw cron job 模板
│   ├── fast_news.json     # 快讯速览模板
│   └── deep_digest.json   # 深度精选模板
├── tests/                 # 100 个测试,pytest
│   ├── test_common.py
│   ├── test_config.py
│   ├── test_dedup.py
│   ├── test_health.py
│   ├── test_integration.py
│   ├── test_new_sources.py
│   ├── test_ranking.py
│   └── test_state.py
├── .github/workflows/
│   └── test.yml           # CI: Python 3.11/3.12/3.13
├── .pre-commit-config.yaml # Ruff + Mypy hooks
└── data/                  # 运行时数据(gitignore)
    ├── .state.fast.json
    ├── .state.deep.json
    ├── source_health.json
    └── push_log.jsonl

开发

# 安装开发依赖
.venv/bin/pip install -e ".[dev]"

# 跑测试
.venv/bin/pytest -v

# Lint + 类型检查
.venv/bin/ruff check .
.venv/bin/mypy .

# Pre-commit hooks
pip install pre-commit
pre-commit install

License

MIT

致谢

About

多源新闻聚合引擎:18 个源 → 三级去重 → 配额排序 → LLM 解读 → 定时推送

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors