This commit is contained in:
Ubuntu
2026-08-06 16:51:39 +08:00
parent a04277e6eb
commit e20c1656b7
82 changed files with 354 additions and 8 deletions
+65
View File
@@ -555,3 +555,68 @@ crawl 流程:
1. `wechat_crawl.py` 是独立路由 `/api/wechat-crawl/`,有自己的 preview/save 两阶段流程,是「微信专用采集器」而非「散落的站点特判逻辑」,不存在重复规则问题
2. 微信的提取逻辑会以 `WechatExtractor` 策略类形式注册到 `crawl_strategies.py`,供通用入口(`universal_fetch` / `crawl_article`)遇到微信 URL 时兜底复用——这是**新增复用**,不改动 wechat_crawl.py 本体
3. 若未来想让 wechat_crawl.py 内部也复用策略类,属于可选优化(消除与 crawl.py 微信段的重复),不在本次重构范围
---
## 九、正文噪音过滤(Pruning 思路,已落地)
### 9.1 背景与动机
HTML → Markdown 转换面对的是整页 DOM,导航栏、侧栏、评论区、相关推荐、
广告等噪音容器会一并进入正文 Markdown,污染文章内容(CSDN 实测整页文本
7505 字符,正文仅 2714 字符,噪音占 64%)。
参考 crawl4ai 的 PruningContentFilter(`/home/ubuntu/forgithub/crawl4ai`
`/crawl4ai/content_filter_strategy.py`)实现本地化方案。
### 9.2 评分模型
对 DOM 递归评分,低于阈值删除:
```
score = 0.4*text_density + 0.2*link_density + 0.2*tag_weight
+ 0.1*class_id_weight + 0.1*text_length
```
- `text_density` = 节点文本 / 节点 HTML 长度,越纯文本越高
- `link_density` = 1 - 链接文本占比,链接越少越像正文
- `tag_weight`:p/article/section/main=1.0~1.5,div/li/td=0.5
- `text_length` = min(log(文本长度+1), 5.0),长度项封顶
### 9.3 相对 crawl4ai 原版的两处修正
1. **长度项封顶 5.0**:原版 `log(text_len+1)` 无上限,超大噪音容器
(如 3600+ 字符的相关推荐列表)得分 0.90 远超阈值 0.48 而残留;
封顶后大容器不再因体量大而误判为正文。
2. **负面类名硬删**:原版对命中负面模式(recommend/comment/sidebar/ads…)
的类名仅 -0.5 小惩罚;本实现直接删除整个子树,因为类名/ID 命中
负面模式的容器几乎必然是噪音。
### 9.4 安全兜底(质量门控)
剪枝后若正文文本 < 300 字符,或 < 原文本的 20%,判定为疑似误删,
回退返回原 HTML。对已定位正文容器的局部 HTML(如 CSDN `#content_views`)
调用时无副作用,正文容器内节点评分普遍高于阈值。
### 9.5 接入点(crawl.py + universal_crawl.py)
新增 `backend/routers/content_prune.py`,`prune_html_noise()` 在**两个
HTML → Markdown 转换函数的统一入口**调用(`fix_encoding` 之后):
- `crawl.py::html_to_markdown()` —— 覆盖 `/api/crawl/` 旧轨
- `crawl.py::convert_spa_html_to_markdown()` —— 覆盖 Playwright SPA 轨
`universal_crawl.py` 的 `_legacy_extract()` 调用上述两个函数(站点特判
分支传已提取的正文容器,SPA/通用分支传整页),**自动获得剪枝,无需
重复调用**(避免双重剪枝开销),仅在调用处加注释说明。
策略轨(`run_extractor → extractor.to_markdown`)同样经由 `crawl.py`
转换函数获得剪枝。
### 9.6 验证结果
- 真实 CSDN 文章页:7505 → 2817 字符(-62%),`#content_views` 正文
保留率 99.8%,博主/评论/点赞/分享/扫码等噪音关键词全部删除
- 构造页面:导航/相关推荐/侧栏/评论区全部删除,正文与 `<pre><code>` 保留
- 质量门控:剪后 2817 > 300 且 38% > 20%,正常通过
- `test_crawl_strategies.py` + `test_crawl.py` 回归:6 passed,无回归