investment-news-collector
🚀 零Token、零API Key的财经资讯自动采集系统
亮点
- 零成本运行:纯Python规则引擎,无需调用任何大模型API,无Token消耗
- 6步智能管线:双源RSS采集 → MD5去重 → 领域过滤 → 标题优先事件评分 → 话题聚类去重 → 正文规则摘要
- 投资信号识别:10类事件类型(含风险预警/政策监管),自动标注🔥/👀/📊三档信号
- 动态公司配置:
config/companies.yaml可编辑,Tier1/Tier2 分档,无需改代码 - Obsidian同步:日报自动生成Markdown格式,可同步到Obsidian知识库
- 内置质量自检:生成时当场校验噪音残留/源侧失衡,另有
health_check.py做区间体检 +health_log.md趋势回溯
架构总览
双源采集(财联社Depth + 华尔街见闻Global)
↓
MD5去重 → 关键词领域过滤(含强排除模式)
↓
标题优先事件分类(10类) + 公司YAML加分 + 金额规模因子 + 时效衰减
↓
话题聚类去重(Containment Coefficient, 阈值0.12 + 前缀快速路径)
↓
正文抓取 + 规则摘要(财联社div.detail-content / 华尔街见闻官方JSON API, 失败降级RSS摘要)
↓
生成日报(6板块Markdown) → 同步Obsidian(可选)
安装
1. Python 依赖
pip install -r requirements.txt
2. 本地 RSSHub
通过 RSSHub 将财联社和华尔街见闻 API 转为 RSS 格式。项目自带 start_rsshub.py。
一次安装:
# 下载 + 解压到 D:\RSSHub
curl -L -o rsshub.zip https://github.com/DIYgod/RSSHub/archive/refs/heads/master.zip
mkdir D:\RSSHub && unzip rsshub.zip -d D:\ && robocopy D:\RSSHub-master D:\RSSHub /E /MOV
# 安装依赖
cd D:\RSSHub
npm install --legacy-peer-deps --cache .npm-cache
3. 配置(可选)
# 设置 Obsidian 知识库路径(留空跳过同步)
OBSIDIAN_DIR = os.environ.get("OBSIDIAN_DIR", "")
# 编辑 config/companies.yaml 调整核心公司分档
4. 运行
# 1. 启动本地 RSSHub(开发模式,无需构建)
python start_rsshub.py
# 或手动: cd D:\RSSHub && node --import tsx lib/index.ts --port 1200
# 2. 采集(约2-3分钟)
python src/finance_main.py
# 3. 关闭 RSSHub(可选)
python start_rsshub.py stop
报告生成在 reports/finance_news_YYYY-MM-DD.md。
数据源
双源并行(带自动降级)
| 源 | 路由 | 场景 | 正文抓取 |
|------|------|------|:--:|
| 财联社深度(主) | localhost:1200/cls/depth | A股IPO/科创板/产业分析 | ✅ ~45% |
| 华尔街见闻(备) | localhost:1200/wallstreetcn/news/global | 全球宏观/美股/科技行业 | ✅ 100%(官方 JSON API) |
任一源挂掉不影响另一端。CLS 已于 2026.06 通过 RSSHub PR #22171 恢复。
⚠️ 为什么需要 RSSHub?
两大财经网站的 API 返回复杂 JSON/Next.js 渲染页面。RSSHub 作为标准化层,统一转为 RSS XML,与现有 feedparser 管线无缝衔接。本地运行,不依赖公共服务实例。
评分逻辑
评分公式
最终分 = (10 基础分 + 事件类型分 + 公司加分 + 创新加分) × 金额规模因子 × 时效衰减
事件类型(10类,标题优先匹配)
2.1.0 起采用标题优先策略:标题命中给全分,仅正文命中降权至 1/3,避免"SpaceX 市值报道"被正文中的"上市"关键词误标为 IPO。
| 类型 | 权重 | 说明 | |------|------|------| | IPO/上市 | 25 | 上市、港股上市、纳斯达克、纽交所 | | 并购重组 | 24 | 并购、收购、重组、私有化 | | 风险预警 | 22 | 泡沫、暴跌、反垄断、实体清单、制裁 | | 融资估值 | 20 | 融资、募资、A/B/C轮、基石、超额认购 | | 政策监管 | 18 | 产业政策、新规、补贴、碳中和 | | 业务里程碑 | 14 | 首发、量产、交付、中标、落地 | | 合作战略 | 12 | 合作、签约、战略、入股、增持 | | 产品发布 | 11 | 发布、推出、上线、开源 | | 财报业绩 | 9 | 财报、净利、营收、业绩预告 | | 市场表现 | 8 | 股价、市值、涨停、回购 |
核心公司加分
动态加载自 config/companies.yaml,编辑即生效:
- Tier1(+8分) — AI算力核心 + 存储龙头:英伟达、OpenAI、台积电、三星、SK海力士、美光、SpaceX 等
- Tier2(+5分) — 科技巨头:特斯拉、腾讯、阿里、Meta、Google、微软、博通、AMD 等
金额规模因子
| 规模 | 乘数 | |------|:--:| | ≥100亿 或 ≥10亿美元 | 1.30 | | ≥10亿 或 ≥1亿美元 | 1.15 | | 含百分比数据 | 1.10 | | 含一般数字 | 1.05 | | 无数字 | 1.00 |
时效衰减
| 新闻年龄 | 系数 | |------|:--:| | < 6小时 | 1.00 | | 6~12小时 | 0.95 | | 12~24小时 | 0.85 | | > 24小时 | 0.70 |
价值等级
- 🔴 头条:≥ 42 分
- 🟠 重要:≥ 32 分
- 🟡 关注:≥ 22 分
- ⚪ 常规:< 22 分
话题聚类去重
解决"同一事件多家报道"问题(2.1.0 增强):
- 精确去重:MD5 哈希(标题)
- 快速路径:标题前 4 中文字符完全匹配 → 直接合并
- 语义去重:中文 2 字 bigram + 英文 token,Containment Coefficient(阈值 0.12)
- 同组保留评分最高的一篇
正文摘要增强
零Token纯规则引擎,从原文提取摘要:
- CSS选择器提取正文(财联社
div.detail-content) - 华尔街见闻改用官方 JSON API(
api-one.wallstcn.com/apiv1/content/{articles|charts|lives}/{id})绕过反爬 SPA 空壳,正文抓取 0%→100% - 逐行噪音过滤:栏目引导语、编辑署名、记者行,以及三类署名/导语缀件一并剥离,输出零署名噪音(正则统一定义在
src/health.py,自检与清理共用同一份,避免两处漂移):- 导语前缀:
财联社/《科创板日报》的M月D日讯(编辑 XXX)。注意「月」必须可省略——同月内媒体会写成「31日讯」,早期写死\d{1,2}月导致该写法整条漏网 - 文首署名块:
(实习编辑 叶可/ 编辑 齐灵)\n正文…(不带「M月D日讯」电头,华尔街见闻常见) - 文末署名块:
…领先地位。(科创板日报记者 徐赐豪) - 三类均要求「编辑/记者 + 空格 + 姓名」,否则会把「(记者获悉)」这类合法引导语误伤——误伤比漏网代价更高
- 导语前缀:
- 导语句 + 数据句拼接(≤500字)
- 抓取失败自动降级为 RSS 原始摘要
- 智能截断:在自然断点处截断;已增强摘要用
has_full_summary标志防止二次压缩
输出格式
生成 Markdown 日报,包含 6 个板块:
- 📊 今日概览 — 价值分布 + 投资信号统计
- 🎯 高价值事件 Top 5
- 💰 投资信号雷达 — 全部信号表格
- 💡 Our Take — 按事件类型分组的全局信号总结
- 📌 Thesis Tracker — 持续追踪的投资命题
- 📋 完整资讯列表(含摘要、标签、链接)
质量自检(2.4.0)
问题不再靠事后人工翻报告发现,而是生成时当场自检 + 事后可回溯。
三层机制
- 生成期自检:
main()在写报告前调用check_news_list(),噪音残留/条目过少/源侧失衡当场告警并打印命中样例 - 命令行体检:
src/health_check.py对任意日期/区间做体检 - 趋势日志:每次结果按日期幂等写入
health_log.md,可看回归与修复效果
用法
python src/health_check.py # 检查今天
python src/health_check.py 2026-08-30 # 指定日期
python src/health_check.py --days 7 # 最近 7 天
python src/health_check.py --all # 全部历史
python src/health_check.py --days 7 --no-log -v # 只输出不写日志,-v 看噪音明细
退出码:存在 FAIL 返回 1,便于串联自动化。
判定口径
| 指标 | 阈值 | 级别 |
|------|------|------|
| 条目数 | < 8 | WARN(多为源侧波动) |
| 条目数 | < 4 | FAIL |
| 单一来源占比 | > 85% | WARN(另一源可能抓取失败) |
| 噪音残留 | > 0 | WARN(导语/文首署名/文末署名/编辑署名行等) |
| 过短摘要占比 | > 30% | WARN(正文抓取大面积失败) |
| 报告缺失 | — | MISSING(离线属预期,不判 FAIL,避免告警疲劳) |
health.py 为纯 stdlib 零依赖,不引入 requests/feedparser,CLI 可秒开。
方法论文方法论来源
2.0.0 起,日报输出理念参考 Anthropic Financial Services 框架:
- Our Take(观点驱动):不只列事件,按类型分组给全局判断
- Thesis Tracker(命题追踪):对重大融资/并购/IPO建立持续追踪标记
- 信号 vs 噪音:明确区分 actionable 信号和背景信息
工程经验
- RSS源选择:主源 CLS Depth,备源华尔街见闻。数据源要有降级链
- 华尔街见闻反爬SPA → 官方JSON API:文章页是反爬 SPA 空壳(requests 直抓正文=0),改用 RSSHub 同款官方 API 后正文抓取 0%→100%(注:该 100% 指文章类,快讯类见下条)
- 增强率 <100% 不等于故障:华尔街见闻快讯(lives,如「据上交所官网,XX 科创板 IPO 审核状态变更为『已问询』」)标题即全文、本身没有正文页,抓取必然失败并降级保留原摘要。排查姿势:先看未增强条目是不是快讯——是则属预期降级,不必动管线;只有文章类批量失败才是真故障(查 API 端点/反爬变更)。此类条目也是「摘要过短」统计的正常来源(2026-09-04 实测 16/18=88.9%,缺口 2 条全是快讯,自检仍 PASS)
- 报告二次压缩陷阱:已做正文增强的条目若再走
condense_rss_summary会被截断为首句——用has_full_summary标志区分,增强摘要保留完整 - 清理逻辑必须覆盖降级路径:只增强成功才走的清理,抓取失败降级的条目会漏网。文末署名首版只加在
generate_rule_summary内,结果降级条目照样带署名——必须在enrich_summaries落库前全局兜底 - 同一类噪音有多种形态:署名会「文首/文末」出现、导语的「月」会省略。修完一种要主动找同类变体,否则只是把洞换个位置
- 误伤比漏网代价更高:漏网只是留噪音且会被自检发现;误伤是静默丢正文。收紧正则时优先保召回安全(如要求「编辑/记者+空格+姓名」排除「(记者获悉)」)
- 多行摘要会破坏 Markdown 引用:
> {text}只给首行加前缀,含\n的摘要第二行起退化为普通段落。必须逐行补> - 缺失不要判 FAIL:离线未跑属预期行为,混进 FAIL 会让退出码天天告警,最终导致告警疲劳、真问题被淹没。单独设
MISSING类 - 解析历史报告要兼容旧格式:档位后曾带「头条」等标签(
🔴 头条 |)。按| 来源:整体切分元数据比硬匹配字段更抗格式漂移 - 标题优先匹配:事件分类以标题为准,正文做辅助(2.1.0 核心改进)
- 采集时间:建议早8-9点后运行(凌晨RSS源偶发异常)
- 相似度算法:关键词 bigram 场景用 Containment Coefficient,别用 Jaccard
- 噪音过滤粒度:行级过滤 > 段落级过滤(财联社正文无空行分隔)。导语前缀正则的「月」必须可省略——同月内媒体会写成「31日讯」,2.3.0 写死
\d{1,2}月\d{1,2}日讯导致该写法整条漏网(2.4.0 修正为(?:\d{1,2}月)?)。现行正则统一定义在src/health.py,勿在别处复制 - 配置外置:公司列表、噪音模式、数据源都支持外部文件编辑
- 按需启停:RSSHub 采集前启动、采集后关闭,不常驻
- 沙箱适配:Windows 沙箱下 git clone 不可用,用 curl+zip 兜底
- RSSHub 增量更新:上游 API 修复时只复制对应路由目录,不需要全量重装
版本规则
三段式 X.Y.Z,与 ai-news-collector 对齐:
| 位 | 含义 | 触发条件 | 示例 |
|:--:|------|----------|------|
| X | 主版本号 | 架构级重构:管线结构、评分体系重建 | 2.0.0 评分系统重构 |
| Y | 次版本号 | 功能变更:新增能力、数据源、输出板块 | 2.4.0 新增质量自检体系 |
| Z | 修订号 | 缺陷修复与输出质量改进,不含新功能 | 2.4.1 修复某类噪音残留 |
历史的两段式版本号统一在末尾补 .0 对齐(2.3 → 2.3.0),语义不变、引用不错位。正文一律写三段式,不再使用两段式简称。
更新日志
- 2.4.0:新增质量自检体系(生成期当场校验 +
health_check.pyCLI 区间体检 +health_log.md趋势日志,缺失单独归类不判 FAIL);修复三类署名/导语残留(文首署名块、同月「31日讯」无「月」写法、多行摘要破坏 Markdown 引用);解析器兼容旧报告格式;噪音正则收敛到src/health.py单一来源 - 2.3.0:新增同源媒体「导语前缀」剥离(
M月D日讯(编辑 XXX));行黏连修复(clean_text由无分隔符拼接改为\n拼接) - 2.2.0:华尔街见闻正文抓取改用官方 JSON API(绕过反爬 SPA 空壳,0%→100%);修复
generate_report二次压缩 bug(新增has_full_summary标志);价值列改为纯 emoji(🔴/🟠/🟡/⚪) - 2.1.0:新增风险预警/政策监管事件类型;公司列表 YAML 动态化;标题优先事件匹配;去重阈值降至 0.12 + 前缀快速合并;Our Take 全局信号总结
- 2.0.0:评分系统重构,10 子类型 + 规模因子 + 时效衰减 + 话题聚类去重
- 1.x.0:CLS 签名变更应对、RSSHub 本地部署、双源降级链建立、技能迁移到 skill 目录
微信扫一扫