← Back to skills
extension
Category: Data & AnalyticsNo API key required

Investment-News-Collector

零Token投资资讯采集系统。从财联社+华尔街见闻双源自动抓取,经6步管线(去重→领域过滤→事件评分→话题聚类→正文摘要→日报生成),输出结构化财经日报。纯Python规则引擎,无需API Key,开箱即用。

personAuthor: user_f0974107hubcommunity

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纯规则引擎,从原文提取摘要:

  1. CSS选择器提取正文(财联社 div.detail-content)
  2. 华尔街见闻改用官方 JSON API(api-one.wallstcn.com/apiv1/content/{articles|charts|lives}/{id})绕过反爬 SPA 空壳,正文抓取 0%→100%
  3. 逐行噪音过滤:栏目引导语、编辑署名、记者行,以及三类署名/导语缀件一并剥离,输出零署名噪音(正则统一定义在 src/health.py,自检与清理共用同一份,避免两处漂移):
    • 导语前缀:财联社/《科创板日报》 的 M月D日讯(编辑 XXX)。注意「月」必须可省略——同月内媒体会写成「31日讯」,早期写死 \d{1,2}月 导致该写法整条漏网
    • 文首署名块:(实习编辑 叶可/ 编辑 齐灵)\n正文…(不带「M月D日讯」电头,华尔街见闻常见)
    • 文末署名块:…领先地位。(科创板日报记者 徐赐豪)
    • 三类均要求「编辑/记者 + 空格 + 姓名」,否则会把「(记者获悉)」这类合法引导语误伤——误伤比漏网代价更高
  4. 导语句 + 数据句拼接(≤500字)
  5. 抓取失败自动降级为 RSS 原始摘要
  6. 智能截断:在自然断点处截断;已增强摘要用 has_full_summary 标志防止二次压缩

输出格式

生成 Markdown 日报,包含 6 个板块:

  • 📊 今日概览 — 价值分布 + 投资信号统计
  • 🎯 高价值事件 Top 5
  • 💰 投资信号雷达 — 全部信号表格
  • 💡 Our Take — 按事件类型分组的全局信号总结
  • 📌 Thesis Tracker — 持续追踪的投资命题
  • 📋 完整资讯列表(含摘要、标签、链接)

质量自检(2.4.0)

问题不再靠事后人工翻报告发现,而是生成时当场自检 + 事后可回溯。

三层机制

  1. 生成期自检:main() 在写报告前调用 check_news_list(),噪音残留/条目过少/源侧失衡当场告警并打印命中样例
  2. 命令行体检:src/health_check.py 对任意日期/区间做体检
  3. 趋势日志:每次结果按日期幂等写入 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.5.0)

health_check.py 查的是产出完整性,统计指标全绿不代表内容可读—— 2026-09-20 实测:同一批报告 health_check 全 PASS,摘要截断率却达 10.5%(09-17 为 22%)。 故新增独立的内容质量视角。

两个工具的分工

| 工具 | 视角 | 查什么 | |------|------|--------| | health_check.py | 产出完整性 | 条目数、双源分布、噪音残留、摘要长度、报告缺失 | | content_audit.py | 内容质量 | 摘要是否被切断、正文残留、栏目聚合帖、信号区分度 |

用法

python src/content_audit.py               # 近 7 天
python src/content_audit.py --days 30     # 近 30 天
python src/content_audit.py --all         # 全部历史
python src/content_audit.py 2026-09-19    # 单日
python src/content_audit.py --days 7 -v   # -v 展开薄摘要明细

检查项

| # | 检查项 | 判据 | |:--:|--------|------| | 1 | 摘要截断 | 引号未闭合(引语被切一半)/ 结尾不是 。!?”》】 | | 2 | 正文残留 | 图注 (…来源:TradingView)、小标题符号 ▍、图片占位 | | 3 | 栏目聚合帖 | 标题含「精选 / 今夜看点 / 研选 / 早餐」等——一条标题塞多家公司,不具代表性 | | 4 | 薄摘要 | < 90 字(多为快讯类预期降级) | | 5 | 信号区分度 | 强烈信号占比 > 50% 提示阈值偏松 | | 6 | 按日期截断率 | 看趋势与回归 |

摘要截断的根因与修复

审计发现 09-03 后仍有 10.5% 摘要被从句子中间切断(…b Stowe表示:、…量减价涨的背离,源于), 且在恶化(09-03~09-09 为 0~9%,09-15 后升至 11~22%)。恶化来自一条因果链: 2.4.0 的多行排版修复让摘要变完整(均长 200→430),更接近 500 字上限,于是更多条目触发硬切。

根因是 generate_rule_summary 旧实现的四个叠加缺陷:

| 缺陷 | 后果 | |------|------| | 拼接允许超拼 > limit + 60 | 先拼到 560 再切回 500,必然切断末句 | | 回退要求句末标点落在后 40%(> 0.6 * limit) | 不满足就原样保留断句 | | 回退只认 。!;,切句却用 。!?; | 漏 ? | | 按标点切句不感知引号 | “…A。 被切成引号未闭合残句(占截断近一半) |

修复方式:抽出两个可单测的纯函数,拼接不再超拼——

  • truncate_at_boundary():一级退到句末标点(含 ?),二级退到分号/逗号并把尾标点收敛为句号,兜底才硬切
  • merge_unclosed_quotes():引号未闭合时向后合并,上限 200 字防失控

单测见 tests/test_rule_summary.py(19 例)。注意:直接在 generate_rule_summary 上造人造长文 往往触发不了真实边界(已踩过),边界条件必须针对抽出的函数构造。

信号区分度与聚合帖降权(2.5.1)

强烈信号阈值 20 → 22:离线回放 224 条历史数据,权重分布为 融资估值(20) 60 条、IPO/上市(25) 53 条、并购重组(24) 13 条、风险预警(22) 7 条。 原阈值 20 把每天 5-6 条的融资类也算强烈信号,导致占比 59%(标签失去区分度)。 提到 22 后只保留 IPO / 并购重组 / 风险预警三类高影响资本事件,占比降至 29%。

栏目聚合帖降权:「港股公告精选」一条标题塞 5-6 家公司、「今夜看点」是盘前播报, 进 Top5 会让头条名不副实。降权而非过滤——非聚合帖不足 5 条时仍递补,条目本身保留在 资讯列表中不丢弃(过滤会误杀"智谱 400 亿融资"这类重要信息)。

文末来源括注:(彭博) 类文末署名纳入噪音库(SOURCE_TAG_RE,$ 锚定文末且括号内 只允许媒体名,避免误伤正文中的「(据彭博社报道)」)。

两类文末噪音漏网修复(2.6.2)

2026-09-23 检查发现两处漏网,都属「只收了一种写法、换个写法就漏」的老问题:

① 来源括注只收了全称:SOURCE_TAG_RE 原本只有「上海证券报」,遇到简称「(上证报)」就漏(#12)。 现按全称/简称成对补齐——界面新闻|界面、每日经济新闻|每经、上海证券报|上证报、 中国证券报|中证报、21世纪经济报道|21财经、澎湃新闻|澎湃 等。

② 免责声明块未识别(新噪音类型):华尔街见闻文末固定套话 「风险提示及免责条款 / 市场有风险,投资需谨慎……据此投资,责任自负。」整块约 100 字进了摘要(#16)。 新增 DISCLAIMER_RE(以块首标题「风险提示及免责条款」为标志,整块丢弃)

  • DISCLAIMER_INLINE_RE(无标题变体,须同时命中开头句与结尾句,避免误伤正文里的「市场有风险」)。 scan_noise() 同步加检测,清理失效时自检会告警。

⚠️ 免责声明的截断在 strip_noise_affixes() 中必须最先执行: 它在文本最尾部,会挡住后面按 $ 锚定的文末署名/括注规则。

实测影响面(新旧规则同跑 1588 条历史语料):仅 27 条(1.70%) 结果不同, 全部为正向清理(20 条剥简称括注 + 7 条剥免责声明),零误伤。

已记录未处理:变体「本文来源:XXX」(如「本文来源:新浪科技」「本文来源:每日经济新闻」), 历史语料约 2 条。

实测效果(2026-09-21 同一天重跑对比)

| 指标 | 2.5.0(修复后) | 2.5.1(本轮) | |------|:--:|:--:| | 摘要截断 | 1/17 | 0 | | 正文残留 | 0 | 0 | | 强烈信号占比 | 47% | 29% |

对比历史基线:截断率从 09-17 的 22%、09-19 的 21% 降到 0;强烈信号从 62% → 29%。

信号标签降权一致性与社会新闻排除(2.5.2)

起因:09-21 日报第 5 条出现「男子造谣"宁德时代宜宾基地班长不让普工上厕所"被行拘」, 一条治安新闻进了 Top5。追查发现是三道关卡依次失守,其中两道是系统性缺陷。

| 关卡 | 实际判定 | 缺陷 | |------|---------|------| | 领域过滤 | 标题含「宁德时代」→ 白名单放行 | CORE_TECH_KEYWORDS 是单条件 OR,只认「提到谁」、不认「发生了什么事」;EXCLUDE_PATTERNS 完全没有社会/治安类模式 | | 事件分类 | 正文含「调查」→ 风险预警 w=22 → 🔥强烈信号 | 降权只减分数、不减标签(见下) | | Top5 排序 | 17 条中排第 5 | 前两关放行后排序已无拦截能力 |

核心 bug(A):_classify_event 对「仅正文命中」有降权设计(event_score = weight // 3, 风险预警 22 → 实际只加 7 分),但 score_and_classify 判 signal_type 时用的是 event_info["weight"] 原始值。于是降权形同虚设——正文里顺带出现「调查/上市/收购」 就能拿到强烈信号标签。离线回放 107 份报告:478/1077 强烈信号属此类,当前阈值口径下仍有 213 条。

修法:仅正文命中时把权重压到 21 分以下,强烈信号必须由标题命中(事件得是文章主题)。 标题命中的判定完全不变,避免误伤。

过滤盲区(B):补 EXCLUDE_PATTERNS 社会/治安类强排除 造谣|谣言|行政拘留|行拘|刑事拘留|警方通报|不实信息|治安管理处罚|寻衅滋事。 这些词出现在财经标题中几乎必然是治安事件;且只做标题匹配,不碰正文。 白名单天然放纵「蹭实体」的内容,必须配一份「事件性质」黑名单才闭环。

实测效果

| 指标 | 2.5.1 | 2.5.2 | |------|:--:|:--:| | 强烈信号占比(回放 1554 条) | 30.8% | 16.7% | | 标签被改判条目 | — | 219 条(14.1%) | | 新排除词命中历史标题 | — | 1 条(就是目标条目,零误伤) | | 09-21 端到端重跑 | 强烈信号 4 条、宁德时代在 Top5 第 4 | 强烈信号 1 条、宁德时代被剔除,Top5 递补为「科创综指基金清盘」「英伟达 Agentic AI」 |

单测 tests/test_signal_filter.py(11 例)覆盖 A/B,并断言「旧实现会失败」以证明用例有效。 另有 tests/test_rule_summary.py(19 例)回归通过。

白名单中英别名与短词边界(2.6.0)

中英不齐:同一实体过去常只有一种写法——有 google 无「谷歌」、有「微软」无 microsoft、 有「台积电」无 tsmc、有「宁德时代」无 catl。只写英文名的报道会被整条过滤掉。 现已成对补齐(tsmc/smic/catl/tesla/nio/xpeng/byd/huawei/alibaba/bytedance/tencent/ baidu/microsoft/apple + 「谷歌」「亚马逊」等)。 「理想」不补 li auto——英文过短且中文「理想」本身歧义大。

短词误命中:子串匹配下 nio 会命中 union/senior/opinion、arm 会命中 biopharmaceuticals。 因此对 <=4 字符的 ASCII 词要求「非字母数字边界」(_kw_matches())。

⚠️ 边界必须用 lookaround,不能用 \b:Python re 默认 \w 含汉字, 「算力GPU需求」中 GPU 两侧不是 \b 边界,实测 \b 会让 gpu 命中数从 76 掉到 18(误杀中文语境缩写)。 改用 (?<![a-z0-9])...(?![a-z0-9]) 后 gpu/cpu/npu/cpo/ipo/llm 零损耗(76→76 / 27→27 / 5→5 / 31→31 / 214→213 / 2→2)。

arm 明确不纳入白名单(误命中 biopharmaceuticals),单测里有回归保护。

实测效果(回放 1571 条)

| 指标 | 结果 | |------|:--:| | 召回损失(旧通过→新不通过) | 9 条(0.57%) | | 其中本就该过滤的无关新闻 | 7 条(反腐 / 黄金 / 大宗商品 / 基金 / 资管 / 金属 / 军工) | | 真实误杀 | 1 条(SpaceXAI 品牌连写,白名单缺 SpaceX) | | 另一条 | 小米汽车(白名单缺「小米」,非边界机制所致) |

净收益为正:边界机制顺带清掉了「潘良被开除党籍」这类反腐新闻—— 正是 2.5.2 遗留的 C 方案想解决的那类误判。

被剔除条目落盘(2.6.1)

每次采集会在 reports/ 下额外产出 excluded_YYYY-MM-DD.json,记录被领域过滤剔除的条目 及剔除原因(no_tech_kw / exclude_pattern:<模式>)。

为什么需要它:评估「补哪些词最划算」不能拿成品语料算。成品是过滤后的存活者, 提到三星/美光/存储的报道基本都已经靠「芯片」「半导体」进来了——在成品里统计词频, 得到的是「领域重要度」,不是「补词的增量收益」。真正漏网的条目此前根本没落盘。

有了这份数据就能回答:

  • 被剔除的条目里,有多少命中了候选新词(补它=捞回这些)
  • 被剔除的条目里,有多少是真不该进的(补词会不会顺带放进噪音)

字段:title / summary(截断 300 字控体积)/ link / source / published / reason。 不传 collect_excluded 时 filter_by_relevance() 行为完全不变(单测有回归保护)。

打包社区版时与 reports/ 一并排除,属本地产物。

方法论文方法论来源

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 类
  • 解析历史报告要兼容旧格式:档位后曾带「头条」等标签(🔴 头条 |)。按 | 来源: 整体切分元数据比硬匹配字段更抗格式漂移
  • 降权/打折逻辑要检查双轨一致性:分值降权了但标签仍按原始值判定,等于降权形同虚设。凡「打折」设计都要确认分值、标签、排序三处用的是不是同一个值
  • 白名单过滤天然放纵「蹭实体」的内容:只认实体不认事件性质,社会新闻提一句公司名就能进。白名单必须配一份「事件性质」黑名单才闭环
  • 离线重跑不能覆盖正式报告:管线各阶段依赖的中间态不同(领域过滤看的是 RSS 原始摘要,而 JSON 里已是增强后的摘要),拿成品 JSON 重跑会因摘要改写而多过滤掉条目(实测多丢 1 条)。重跑只用于同输入同流程的 A/B 对比,正式产物仍走完整采集
  • 英文关键词边界不能用 \b:Python re 默认 \w 含汉字,中文语境里的缩写(「算力GPU需求」)两侧没有 \b 边界,实测 gpu 命中数 76→18。必须用 lookaround 排除 ASCII 字母数字
  • 改词表要先量化召回损失:「通过→不通过」的误杀代价高于误放行。补别名/收边界后都要回放历史语料,确认损失条目是不是本就该过滤的;只有无关新闻被清掉才算净收益
  • 对照用例的 summary 不能带旧词表里的词:验证「新别名让条目通过」时,若 summary 里含「台积电」「芯片」等旧关键词,旧实现也会通过,对照就失效了
  • 评估词表收益要先有「被剔除」的样本:过滤后的成品语料测不出漏网——存活者靠通用词(芯片/半导体)进来,统计它们的词频只反映领域重要度。加一道落盘才有量化依据
  • 标题优先匹配:事件分类以标题为准,正文做辅助(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 新增质量自检体系;2.6.0 补齐白名单中英别名 | | Z | 修订号 | 缺陷修复,以及不改变产物的内部改动(可观测性落盘、单测、重构、文档) | 2.6.1 被剔除条目落盘(不传参时行为不变) |

判定 Y 还是 Z,关键问一句:使用者看到的日报会不会变? 会变 → Y;不会变(只服务于排查/评估/测试)→ Z。

⚠️ 反面案例:2026-09-22 曾把「被剔除条目落盘」定为次版本号 2.7.0, 但它不改报告、不新增可用工具、不传参时行为都不变,事后回退为 2.6.1。

发版纪律:一个主题发一个版本,不在单次改动后就发版。 同一主题的连续步骤(如「补白名单别名」→「为评估补词收益加落盘」)先合并再发, 避免一个晚上连跳两个次版本号。

历史的两段式版本号统一在末尾补 .0 对齐(2.3 → 2.3.0),语义不变、引用不错位。正文一律写三段式,不再使用两段式简称。

更新日志

  • 2.6.2:修复两类文末噪音漏网——① SOURCE_TAG_RE 只收了媒体全称,简称「(上证报)」「(每经)」「(中证报)」「(21财经)」等漏网,现按全称/简称成对补齐;② 新增免责声明块识别(华尔街见闻文末固定套话「风险提示及免责条款…据此投资,责任自负。」约 100 字),DISCLAIMER_RE + 无标题变体 DISCLAIMER_INLINE_RE,并在 strip_noise_affixes() 中最先执行(否则挡住按 $ 锚定的尾部署名规则)。scan_noise() 同步加检测。实测影响 1588 条中 27 条(1.70%),全部正向清理、零误伤
  • 2.6.1:filter_by_relevance() 新增可选参数 collect_excluded,被剔除条目连同原因落盘为 reports/excluded_YYYY-MM-DD.json(title / summary 前 300 字 / link / source / reason)。不传参时行为完全不变。用途:白名单补词的收益只能拿这批数据量化——成品语料里提到某公司/概念的报道多半是靠「芯片」等通用词进来的,测不出真实漏网
  • 2.6.0:补齐 CORE_TECH_KEYWORDS 中英别名(同一实体过去常只有一种写法:有 google 无「谷歌」、有「微软」无 microsoft、有「台积电」无 tsmc),新增 tsmc/smic/catl/tesla/nio/xpeng/byd/huawei/alibaba/bytedance/tencent/baidu/microsoft/apple 及「谷歌/亚马逊」等。新增短词边界匹配 _kw_matches():<=4 字符的 ASCII 词要求非字母数字边界,避免 nio→union/senior、arm→biopharmaceuticals 误命中。新增单测 tests/test_whitelist.py 11 例
  • 2.5.2:修复「信号标签降权不一致」——_classify_event 对仅正文命中已降权计分(weight//3),但 score_and_classify 判标签仍用原始 weight,导致正文里顺带出现「调查/上市/收购」就能拿 🔥 强烈信号(回放 107 份报告:478/1077 强烈信号属此类)。现改为仅正文命中时压到 21 分以下,强烈信号必须由标题命中。EXCLUDE_PATTERNS 补社会/治安类强排除(造谣|行拘|行政拘留|警方通报|不实信息 等),堵住「领域过滤只看实体白名单、不看事件性质」的盲区(「男子造谣宁德时代…被行拘」曾长驱直入并进 Top5)。新增单测 tests/test_signal_filter.py 11 例
  • 2.5.1:强烈信号阈值 weight 20→22(只保留 IPO/并购/风险预警,占比 59%→29%);栏目聚合帖在 Top5 降权(非聚合帖优先,不足才递补,条目不丢弃);新增文末来源括注 (彭博) 清理;摘要结尾分号/逗号规范化为句号
  • 2.5.0:新增内容质量审计 src/content_audit.py(摘要截断 / 正文残留 / 栏目聚合帖 / 信号区分度);修复摘要被从句子中间切断(抽出 truncate_at_boundary() 与 merge_unclosed_quotes(),拼接不再超拼、回退补 ?、加逗号二级兜底);新增正文残留清理(小标题符号 ▍、图注 (…来源:TradingView),图注只摘片段不整行删以免误伤同行正文);单测 tests/test_rule_summary.py 14 例
  • 2.4.0:新增质量自检体系(生成期当场校验 + health_check.py CLI 区间体检 + 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 目录