一开始以为docx解析一切,后来发现远没有那么简单。
这里探讨的是docx文件,doc文件比较麻烦,最好在windows平台上处理成docx文件。两者的区别是doc格式比较早office 2003,存储的是二进制格式,docx存储的是xml文件等组成的压缩包,存储容量更小。
这篇文章没给代码,基于提示去问问大模型怎么写,根本记不住。
一、Document
from docx import Document
提取段落 .paragraps
提取表格 .tables
获取每个元素的类型 .element.body 其中.tag.endswith p为段落,tbl为表格,secPr为章节?,bookmarkStart、bookmarkEnd为书签
获取段落的分页信息 ._element.xml 包含lastRenderedPageBreak
获取样式 .style.name 可以获知其是一级标题?二级标题?
获取字号 从paragraps的runs中提取font.size
二、zipfile解压.docx文件
如果用终端vim xxx.docx,会看到一堆文件让选择,但是vim并不能真正显示出这些文件的内容。用zipfile可以将.docx的内容解压到一个文件夹
import zipfile
with zipfile.Zipfile(file_path,'r')as f:
f.extractall(output_path)
文档中嵌套的文档可以在word/media或word/embeddings下找一找
主要文件在word/document.xml
页脚文件在word/footer*.xml
页眉毛文件在word/header*.xml
三、嵌套文件
有2种情况,后面链接到了本地一个文件,根据路径找到对应文件,或者文件作为附件真正被插入到文档中。
情况一:链接
用docx找一下oleObject
document = Document(f_path)
for rel in document.part.rels.values():
if 'oleObject' in rel.reltype:
print(rel.target_ref)
oleobject:代表工作表上的一个 ActiveX 控件或链接或嵌入的 OLE 对象
OLEObject 对象 (Excel) | Microsoft Learn
情况二:附件
用zipfile解压后找一下
四、基于langchain的RecursiveCharacterTextSplitter拆分文件
按照分隔符迭代拆分
139 深入解析 RecursiveCharacterTextSplitter 类 langchain_text_splitters.charater.py-CSDN博客
五、基于langchain的 Docx2textLoader
本质是用docx2txt(一个可以用pip安装的库)提取page_content信息,再用自定义的Document进行管理。docx2txt的功能具体看:
七
缺点:
1、没有分离页眉页脚
2、不能保留表格,每个单元格都变成了一行
3、附件没有
六、基于ragflow的RAGFlowDocxParser
本质还是用docx实现的,考虑了段落的分页情况,可以提取起止页间的段落
七、docx2txt
lainchain的底层,可以对word文件解压后提取页眉、主文本、页脚、图片
八、复杂合并单元格的表格
从docx的xml源文件解析复杂表格,试过多种开源的docx解析方案,对复杂表格的解析都不好,会丢失格式信息。尝试自己来解析,获得准确的列信息,解析word/document.xml文件,获得一个大xml,可以发现,段落和表格的信息都在其中,奇怪的是,这个xml会进行奇奇怪怪的断句。将表格前后的xml内容复制,在xml在线解析网页中格式化,可以看到清晰的表格格式。<w:tbl></w:tbl>表示表格,<w:tr></w:tr>是行信息,<w:tc></w:tc>是单元格信息(cells),<w:t></w:t>是文本信息。用xml.etree.ElementTree解析后所有数据是一个tree的形式,而不是list的形式,用findall、find、get来获得下一级的信息。列合并看gridSpan,可以直接看到列合并数量,如<w:gridSpan w:val="2"/>指2个单元格合并为1个。行合并看VMerge,<w:vMarge w:val="restart"/>指行合并的首行,<w:vMarg/>指行合并的非首行。