直接回答:采集流水线的核心不是"抓下来",而是把网页变成一条条语义完整、可独立检索的片段。可落地的流程是五步:抓取 → 正文提取 → 按标题切分 → 质量打分 → 结构化与向量入库,并配套一套失败降级策略。

流水线全貌

内容采集与结构化流水线:抓取、正文提取、标题切分、质量打分、入库

五个环节里,"标题切分"是对最终效果影响最大的一步,也是最容易被草率处理的一步。下面逐个说明。

一、抓取:先解决"能不能进得来"

抓取环节的关键约束不是速度,而是不被封、不浪费时间

我用的是这套参数:

参数 取值 理由
单域名并发 2 兼顾效率和礼貌性,降低被封概率
请求超时 15 秒 超过这个时间基本可以判定不可用
重试次数 3 次,退避 2s / 8s / 30s 覆盖偶发抖动,又不至于死等
User-Agent 明确的机器人标识 + 联系方式 出问题时对方能找到你
增量判断 last-modified + 正文哈希 内容没变就不重复入库

关于 robots.txt平台默认遵守,不提供绕过选项。 这是底线——一个能"绕过规则"的工具,最后往往会把麻烦留给你自己。

二、正文提取:通用算法 + 定向规则

中文站点的正文提取有两个坑:

  1. 部分页面正文在 div 里而不是 article 标签里,通用算法会漏。
  2. 有些站点把推荐阅读、作者简介混在正文区域,通用算法会多。

我的处理策略是分层的:

1
2
3
第一层:通用算法(可读性打分)        → 覆盖约 80% 的站点
第二层:站点专用选择器(按域名配置) → 覆盖高频目标站点
第三层:人工复核队列 → 处理前两层都失败的页面

专用选择器配置化,不用改代码:

1
2
3
example.com:
content: "article.post-content"
remove: [".ad", ".related-posts", ".author-box"]

实测下来,加上第二层之后,正文提取的准确率从 78% 提升到 96%,而需要人工复核的比例从 22% 降到 4%。

三、标题切分:决定检索质量的一步

为什么按标题切

固定长度切分的最大问题是会把一个完整论证切成两半,或把两个不相关的主题拼在一起。按 h2 / h3 切分则天然尊重作者组织内容的边界。

实测的粒度对比

我在同一批 1200 篇文章上做了对比,用"能否在检索时找回原文对应段落"作为评价标准:

切分粒度 平均长度 检索命中率 备注
固定 200 字 200 71% 上下文丢失严重
固定 500 字 500 83% 跨界拼接问题明显
固定 1000 字 1000 79% 一个片段内主题混杂
按标题切分 平均 480 92% 语义边界清晰
按标题切分 + 超长二次切分 平均 460 93% 长小节不再被截断

结论很明确:按标题切分并给超长小节做二次切分,是性价比最高的方案。

具体规则

1
2
3
4
1. 以 h2 / h3 为边界切分,标题作为该片段的 caption
2. 片段超过 700 字时,按句子边界二次切分,重叠 80 字
3. 片段小于 120 字时,与前一个片段合并
4. 每个片段保留:所属文章标题、URL、发布时间、h1-h3 路径

第 4 条特别重要。片段单独被检索出来时,只有带上"它来自哪篇文章的哪一节",才有可解释性。

四、质量打分:筛掉脏数据

抓来的内容不都需要入库。我用了一个简单的加权打分:

维度 权重 判断方式
有效长度 30% 中文正文字符数
事实密度 25% 数字、年份、专有名词占比
结构完整度 20% 是否有明确的标题层级
内容重复度 15% 与库内已有片段的相似度
元信息完整 10% 是否有作者、日期、来源

总分低于 0.4 的片段进人工复核队列,高于 0.75 的直接入库并提高检索权重。

这一步的价值在排查问题时特别明显。 没有质量分层,检索结果不准确时你无法判断是算法问题还是数据问题,只能盲调参数。

五、入库:结构化与向量并存

每个片段在数据库里存两份信息:

1
2
3
4
5
-- 结构化字段:用于过滤和排序
article_url, article_title, heading_path, published_at, updated_at, source_type

-- 向量字段:用于语义检索
embedding vector(1024)

检索时先按结构化条件过滤(例如"只查近一年、只查技术类"),再做向量相似度排序。先过滤再检索,比全量检索快一个数量级,也更准。

失败与降级

流水线必须假设每一步都会失败:

1
2
3
4
抓取失败  → 重试 3 次 → 仍然失败则记录并跳过,不阻塞队列
提取失败 → 尝试站点专用规则 → 仍失败进入人工队列
切分异常 → 退化为按段落切分,并标记低置信度
向量化失败 → 保留结构化数据,标记待补向量,可事后重跑

原则是:任何一环失败都不应该让整批任务停住。 我早期的版本就是因为一条坏数据让整个队列卡了 6 小时。

常见问题(FAQ)

片段切多大比较合适?

实测 300 到 700 个中文字符是较优区间。太小会丢失上下文,太大则一段里混杂多个主题,向量表示被平均掉,检索准确率反而下降。按标题层级切分、再对超长小节做二次切分,是稳定可用的做法。

正文提取用现成库还是自己写规则?

先上现成库处理 80% 的常规页面,再针对高频目标站点补专用规则。完全自己写规则的成本远高于预期,而完全依赖通用库在部分中文站点上会丢掉正文。

质量打分有什么用?

它决定了哪些内容进入检索库、哪些需要人工复核。没有打分,低质量页面会稀释检索结果,让你在排查问题时误以为是检索算法不准,实际上是数据脏。

下一篇

数据进来之后,最有价值的一层是它到底有没有被 AI 引用《自建 GEO 平台(三):AI 收录监测与效果度量》


你的流水线里如果遇到类似的坑,欢迎到留言板说说,也许有更省事的做法。

站内搜索

没有找到内容!