Word 知识库材料怎么解析?保留标题层级、段落和表格顺序

用 python-docx 按原文顺序解析 DOCX,保存标题路径、段落与表格记录;通过交错样例验证表格位置,并说明修订、图片和复杂表格的边界。

把 Word 材料交给 AI 知识库前,先保存“这段文字属于哪一节、表格在什么位置、来自哪个文件”。只先读取所有段落再读取所有表格,会破坏两者在原文中的交错顺序,也可能让检索片段失去上下文。

下面用 python-docx 把主文档中的段落和表格按顺序转成 JSON。示例是人为构造的 Word 文档,已在 Windows、Python 3.11.15、python-docx 1.2.0 环境运行;没有连接在线知识库,也没有验证问答准确率。

Word 知识库材料怎么解析?保留标题层级、段落和表格顺序

先确定输入和记录结构

输入是可编辑的 .docx 文件。本例不接受旧版 .doc,也不会对扫描图片执行 OCR。先复制一份原文件用于解析,并保留原件,避免把资料转换与修改内容混在一起。

Document 官方接口提供 iter_inner_content(),按文档顺序产生 Paragraph 或 Table。程序对两种对象分别记录内容,共用同一个 order;标题段落同时更新 heading_path,后面的正文和表格沿用该路径。

字段 用途
order 当前块在主文档迭代序列中的位置,从 0 开始
kind 区分 heading、paragraph 和 table
heading_path 保留当前一级、二级等标题组成的路径
text / rows 段落文字或按行排列的表格单元格文字
source_file 保存来源文件名;接入多文件库时还应补文档唯一 ID

按样式识别标题,而不是按字号猜

样式文档指出,style.name 用于访问样式,style_id 由 Word 自动生成,不保证跨保存稳定。因此本例明确把 Heading 1 到 Heading 9 映射为标题级别,不依据内部 style_id 识别。

如果你的文档使用自定义样式或显示名称与映射不同,先打印各段落的 paragraph.style.name,把真实名称加入 heading_levels,例如 {"章标题": 1, "节标题": 2}。只有手工放大字号而没有应用标题样式的段落,本例会当普通正文处理。

运行完整的交错顺序示例

在独立目录安装 python -m pip install python-docx==1.2.0。将下面代码保存为 parse_docx.py,执行 python parse_docx.py。它先创建带标题、段落、表格的演示文件,再解析并检查顺序。

from pathlib import Path
import json
from docx import Document
from docx.text.paragraph import Paragraph

sample=Document()
sample.add_heading('演示知识库材料',level=1)
sample.add_paragraph('这是人为构造的文档,用于验证解析顺序。')
sample.add_heading('安装步骤',level=2)
sample.add_paragraph('先建立独立环境,再核对包版本。')
table=sample.add_table(rows=2,cols=2)
table.cell(0,0).text='检查项';table.cell(0,1).text='预期结果'
table.cell(1,0).text='环境';table.cell(1,1).text='版本已记录'
sample.add_paragraph('表格之后继续执行输入检查。')
sample.add_heading('验收方法',level=2)
sample.add_paragraph('保存原文件与解析记录,抽查段落和表格顺序。')
sample.save('sample_knowledge.docx')

def parse_docx(path):
    document=Document(path)
    heading_levels={f'Heading {level}':level for level in range(1,10)}
    headings=[]
    result=[]
    for order,block in enumerate(document.iter_inner_content()):
        if isinstance(block,Paragraph):
            text=block.text.strip()
            level=heading_levels.get(block.style.name if block.style else '')
            if level and text:
                headings=[pair for pair in headings if pair[0]<level]
                headings.append((level,text))
                kind='heading'
            else:
                kind='paragraph'
            if not text:
                continue
            result.append({'order':order,'kind':kind,'heading_path':[x[1] for x in headings],
                           'text':text,'source_file':Path(path).name})
        else:
            result.append({'order':order,'kind':'table','heading_path':[x[1] for x in headings],
                           'rows':[[cell.text for cell in row.cells] for row in block.rows],
                           'source_file':Path(path).name})
    return result

records=parse_docx('sample_knowledge.docx')
tables=[x for x in records if x['kind']=='table']
assert len(tables)==1
table_pos=records.index(tables[0])
assert records[table_pos-1]['text']=='先建立独立环境,再核对包版本。'
assert records[table_pos+1]['text']=='表格之后继续执行输入检查。'
assert tables[0]['heading_path']==['演示知识库材料','安装步骤']
assert records[-1]['heading_path']==['演示知识库材料','验收方法']
Path('docx_records.json').write_text(json.dumps(records,ensure_ascii=False,indent=2),encoding='utf-8')
print('records:',len(records))
print('table_records:',len(tables))
print('table_between_correct_paragraphs:',True)
print('last_heading_path:',records[-1]['heading_path'])
print('saved: docx_records.json')

本地运行输出

records: 8
table_records: 1
table_between_correct_paragraphs: True
last_heading_path: ['演示知识库材料', '验收方法']
saved: docx_records.json

怎样核对 JSON 确实对应原文

本例输出 8 条记录,其中 1 条是表格。表格前一条为“先建立独立环境,再核对包版本。”,后一条为“表格之后继续执行输入检查。”;表格路径为“演示知识库材料 → 安装步骤”,最后一段路径为“演示知识库材料 → 验收方法”。代码同时用断言检查这些关系,异常时直接停止。

打开 sample_knowledge.docx 与 docx_records.json,按 order 逐条比对标题、段落和表格位置。实际资料至少抽查标题跳级、表格前后说明、关键限制条件和文末段落;记录数正确并不证明内容完整。

改成你自己的 Word 材料

  1. 保留 parse_docx 函数,删掉前面创建 sample 的演示部分。
  2. 把调用改为 records = parse_docx('自己的文件.docx'),输出文件也换成对应名称;不要将自己的原件命名为演示输出文件。
  3. 用真实样式名称补充 heading_levels;没有样式的文件先在副本中规范标题。
  4. 按 kind 把段落与表格送入后续切分,保留 source_file、文档 ID 和原块位置;如果表格单独切片,把所属标题和表头一起带入。
  5. 选实际会向知识库提出的问题,确认它所需的句子与表格信息都还在转换结果中,再进行向量化。

哪些情况要另加解析规则

本例只遍历主文档层的段落和表格,不保证完整覆盖页眉页脚、文本框、修订记录、图片、嵌套表格或合并单元格的语义。合并单元格在按 row.cells 遍历时可能重复出现,必须对照原表处理,不能直接把重复文字当多条独立事实。

出现“原文有内容、JSON 没有”的情况,先确认文字是否在图片、文本框或修订区域,再选择相应处理方式。不要让模型补写漏掉的数字或条件。正文文字成功读取,也不意味着图中的尺寸、公式或流程已被读取。

标题不连续,会不会报错?

本例允许从一级直接跳到三级,并保留实际出现的路径,不会补造不存在的二级标题。如果下游要求固定层数,应单独记录缺层情况;不要凭空添加一个标题来让结构看起来完整。

Ai菜鸟网。发布者:AI小管家,转载请注明出处:https://www.alyyhw.com/31894.html

赞 (0)
AI小管家的头像AI小管家
豆包账号怎么注销?先检查关联服务,再提交注销申请
上一篇 2小时前
网页怎么整理成 AI 知识库资料?用 Trafilatura 提取正文并保留来源
下一篇 2小时前

相关推荐

联系我们

联系我们

1

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信
关注微信
分享本页
返回顶部