把网页整理成 AI 知识库材料时,先把正文与导航、页脚、评论分开,再保留来源网址和原始文件。直接把整页可见文字拼进知识库,会让登录提示、订阅广告或菜单重复占据检索片段;只留下正文而丢掉来源,又会让后续引用难以核对。
下面用 Trafilatura 处理一份本地 HTML,并将正文、标题、原文件哈希与来源标识保存到 JSON。输入是人为构造的演示网页,已在 Windows、Python 3.11.15、trafilatura 2.2.0 环境运行;没有抓取真实文章,也没有做检索效果评测。

准备 HTML,并明确“来源”是什么
本例先创建 sample_article.html,其中有导航、三段正文与页脚。source_url 使用 https://example.invalid/knowledge-demo 这个虚构标识,只表示演示记录的来源字段;程序没有访问它。
extract 接口说明把网页内容与 url 分开接收。传入 url 不会替你验证该内容确实来自这个网址;应用需要自己保存下载结果和真实来源之间的对应关系。
处理真实资料时,先保存你有权处理的页面 HTML,并记录原网址、获取时间及原文件。这里的 SHA-256 用于区分原文件字节是否变化,不证明文章事实正确,也不能代替来源许可。
设置正文提取参数
Python 用法文档支持 JSON 输出和附带元数据。本文设置 output_format="json"、with_metadata=True、include_comments=False、include_tables=True:希望排除评论,同时尝试保留表格文字。
这些是提取配置,不能保证每个站点都被正确识别。本例没有复杂表格,不能据此宣称表格列对应关系已被完整保留。若表格中的一列数值需要另一列单位才能解释,提取后要专门检查这种关系。
复制代码并生成来源记录
安装 python -m pip install trafilatura==2.2.0。将下面完整代码保存为 extract_web.py,执行 python extract_web.py。它会生成 sample_article.html 与 web_source_record.json。
from pathlib import Path
import hashlib,json
import trafilatura
sample='''<!doctype html><html lang="zh"><head><title>知识库资料核对示例</title>
<meta property="og:title" content="知识库资料核对示例"></head><body>
<nav>首页 | 联系我们 | 订阅会员</nav><main><article>
<h1>知识库资料核对示例</h1>
<p>这是人为构造的网页正文,用于验证主内容抽取。建立知识库之前,应先检查输入材料来源,保留原始文件,并记录每次转换采用的规则。</p>
<p>正文抽取需要保留具体操作和约束。不能因为页面标题正确,就忽略模型回答所需要的表格、脚注和限制说明。抽取之后需要与原始页面逐段对照。</p>
<p>如果原始文件只有导航而没有正文,应记录抽取失败,继续核对页面是否依赖脚本加载。无法确认的文字不能凭猜测加入知识库材料。</p>
</article></main><footer>版权与订阅 | 账户设置</footer></body></html>'''
Path('sample_article.html').write_text(sample,encoding='utf-8')
source_url='https://example.invalid/knowledge-demo'
raw=Path('sample_article.html').read_bytes()
result=trafilatura.extract(raw.decode('utf-8'),url=source_url,
output_format='json',with_metadata=True,
include_comments=False,include_tables=True)
if result is None:
raise ValueError('No main text extracted')
parsed=json.loads(result)
text=parsed.get('text','').strip()
if not text:
raise ValueError('Extracted JSON has no usable text')
assert '输入材料来源' in text
assert '不能凭猜测加入知识库材料' in text
assert '首页 | 联系我们' not in text
record={'source_url':source_url,'source_file':'sample_article.html',
'source_sha256':hashlib.sha256(raw).hexdigest(),'title':parsed.get('title'),
'text':text,'extracted_metadata':parsed}
Path('web_source_record.json').write_text(json.dumps(record,ensure_ascii=False,indent=2),encoding='utf-8')
print('title:',record['title'])
print('main_text_chars:',len(text))
print('navigation_removed:',True)
print('required_boundary_text_retained:',True)
print('saved: web_source_record.json')
本地运行输出
title: 知识库资料核对示例
main_text_chars: 197
navigation_removed: True
required_boundary_text_retained: True
saved: web_source_record.json
这次运行验证了什么
本例提取出标题“知识库资料核对示例”和 197 个字符的主文本。断言验证了导航中的“首页 | 联系我们”没有进入结果,以及正文中的输入来源要求和“不能凭猜测加入知识库材料”仍然存在。
打开 web_source_record.json,把 text 与原 HTML 中三段正文逐段对照。先检查关键动作、数字、条件和否定句有没有丢失,再检查导航和页脚残留;不能只看标题正确就通过。
record 中保留 source_url、source_file、source_sha256 和 extracted_metadata。向知识库导入时,给后续切片带上文档 ID 与 source_url;原文件单独保存,以便回答出现疑问时回读原始资料。
替换为你的网页材料
- 删除创建 sample 的演示部分,保留从文件读取、extract 和写出 JSON 的处理流程。
- 把 source_file 和读文件位置改成实际保存的 HTML,source_url 改成该文件对应的真实原网址。
- 确认文件编码;示例使用 UTF-8,读取失败时应先处理编码,不用忽略错误的方式吞掉文字。
- 根据任务选择评论、表格与链接是否保留。产品答疑可能需要正文中的例外条款,论坛研究可能需要评论,不能把同一配置套到所有来源。
- 对样本页完成原文对照后再批量转换;失败记录留待处理,不让空字符串进入后续向量化。
正文为空或缺段时怎么处理
extract 返回 None,或 JSON 的 text 为空时,代码明确报错。先打开原 HTML 确认是否包含正文;如果只保存了外壳、脚本和导航,继续调整提取参数也不会凭空出现正文。
Trafilatura 的这次用法处理传入的 HTML,不会执行网页 JavaScript。对于运行脚本后才加载的页面,需要先获取实际包含正文的内容,再提取;本文没有验证登录页面、付费页面或动态站点的采集流程。
正文缺少脚注、表格或限制说明时,回读原页面并决定采用结构化 HTML/XML 输出或单独记录该部分。关键条件缺失的材料先修正,不让模型根据残缺材料补写答案。
网页更新后,原文件哈希能替代文档 ID 吗?
不能。哈希随文件字节变化,适合标记版本;文档 ID 应稳定对应同一来源。更新时同时保留文档 ID、版本哈希和获取时间,下游按你的版本规则替换旧片段。本例只提取并保存一份资料,没有实现知识库更新操作。
Ai菜鸟网。发布者:AI小管家,转载请注明出处:https://www.alyyhw.com/31897.html