RAG 文档解析实战:PyMuPDF 与 Unstructured 的使用

📅 2026/6/16 21:16:18
RAG 文档解析实战:PyMuPDF 与 Unstructured 的使用
目录一、RAG 为什么需要文档解析二、PyMuPDF 和 Unstructured 的定位区别三、PyMuPDF 简介四、PyMuPDF 基础用法1. 提取 PDF 文本2. 提取文本块3. 提取字典结构4. 把 PDF 页面渲染成图片5. 提取 PDF 中的图片6. 表格提取五、PyMuPDF 在 RAG 中的推荐用法1. 普通 PDF 文本知识库2. 扫描件 PDF3. 图片较多的 PDF4. 表格较多的 PDF六、Unstructured 简介七、Unstructured 基础用法1. 自动解析文档2. 解析 PDF3. 解析图片八、Unstructured 的 Title 是怎么来的九、Unstructured Chunking 用法1. 按标题切 Chunk2. 为什么 Unstructured 的 chunking 和普通文本切分不同十、QA 格式文档怎么处理QA 数据向量化问题还是答案十一、QA 里有图片怎么办十二、QA 里有表格怎么办十三、PyMuPDF 与 Unstructured 的组合方案方案 1Unstructured 主导方案 2PyMuPDF 主导方案 3混合方案十四、RAG 入库数据结构推荐十五、总结一、RAG 为什么需要文档解析RAG 的完整流程通常是原始文档 - 文档解析 - 文本清洗 - Chunk 切分 - 向量化 - 写入向量库 - 检索 - LLM 生成回答在这个流程里文档解析非常关键。如果 PDF、Word、图片、表格在解析阶段就被处理坏了后面的向量检索和问答效果都会下降。常见问题包括PDF 提取出来文字顺序错乱扫描件 PDF 没有可复制文本表格被拆成一堆无意义的行图片里的文字没有 OCR标题和正文没有结构Chunk 切得太碎或太长检索结果没有页码、来源、章节信息。PyMuPDF 和 Unstructured 都是 RAG 文档处理里常见的工具但它们定位不同。二、PyMuPDF 和 Unstructured 的定位区别工具核心定位更适合做什么PyMuPDFPDF 底层解析与页面处理库提取文本、图片、坐标、页面渲染、表格检测Unstructured多格式文档解析与结构化预处理框架把 PDF、Word、HTML、图片等解析成结构化 Element并支持 chunk可以简单理解PyMuPDF 更像 PDF 手术刀。 Unstructured 更像 RAG 文档预处理流水线。如果你只处理 PDF并且想要更细粒度控制页面、坐标、图片、表格PyMuPDF 很合适。如果你要处理多种格式例如 PDF、DOCX、HTML、PPTX、图片并希望直接拿到Title、NarrativeText、Table等结构化元素Unstructured 更方便。三、PyMuPDF 简介PyMuPDF 是一个高性能 Python 文档处理库底层基于 MuPDF。它可以处理 PDF、XPS、EPUB 等格式。RAG 中最常用的是 PDF 解析。安装pipinstallpymupdf导入方式importfitz注意PyMuPDF 的导入名是fitz。四、PyMuPDF 基础用法1. 提取 PDF 文本importfitz docfitz.open(demo.pdf)forpage_index,pageinenumerate(doc):textpage.get_text()print(f第{page_index1}页)print(text)page.get_text()默认提取纯文本适合普通可复制文本 PDF。如果是扫描件 PDF可能提取不到文字需要先 OCR。2. 提取文本块importfitz docfitz.open(demo.pdf)pagedoc[0]blockspage.get_text(blocks)forblockinblocks:print(block)blocks会返回带坐标的文本块常用于分析页面布局判断标题和正文按区域抽取内容保留页码和坐标 metadata。3. 提取字典结构importfitz docfitz.open(demo.pdf)pagedoc[0]datapage.get_text(dict)forblockindata[blocks]:ifblock[type]0:forlineinblock[lines]:line_text.join(span[text]forspaninline[spans])print(line_text)dict结构里有更详细的字体、字号、坐标信息。你可以根据字号、加粗、位置来粗略判断标题。4. 把 PDF 页面渲染成图片importfitz docfitz.open(demo.pdf)fori,pageinenumerate(doc):pixpage.get_pixmap()pix.save(fpage_{i1}.png)如果想提高图片分辨率importfitz docfitz.open(demo.pdf)pagedoc[0]matrixfitz.Matrix(2,2)pixpage.get_pixmap(matrixmatrix)pix.save(page_1_2x.png)这在 OCR、视觉模型理解、图片问答中很常用。5. 提取 PDF 中的图片importfitz docfitz.open(demo.pdf)forpage_index,pageinenumerate(doc):imagespage.get_images(fullTrue)forimage_index,imginenumerate(images):xrefimg[0]base_imagedoc.extract_image(xref)image_bytesbase_image[image]image_extbase_image[ext]image_pathfpage_{page_index1}_image_{image_index1}.{image_ext}withopen(image_path,wb)asf:f.write(image_bytes)RAG 中图片一般不要直接向量化原图而是图片 - OCR / caption - 文本描述参与向量化 原图路径 - metadata 保存用于回答时引用或展示6. 表格提取PyMuPDF 新版本支持页面表格检测。典型用法类似importfitz docfitz.open(demo.pdf)pagedoc[0]tablespage.find_tables()fortableintables:dftable.to_pandas()print(df)注意表格检测依赖 PDF 版面质量复杂跨页表格、无线框表格可能识别不稳定如果表格很重要建议结合pdfplumber、Camelot、Tabula 或 Unstructured 的表格能力做对比。五、PyMuPDF 在 RAG 中的推荐用法1. 普通 PDF 文本知识库PyMuPDF 提取文本 - 按页保存 page metadata - 清洗页眉页脚 - 按标题或段落切 chunk - 向量化示例数据结构{content:这里是第 3 页中的一段正文...,metadata:{source:manual.pdf,page:3,type:text}}2. 扫描件 PDFPyMuPDF 渲染页面图片 - OCR - 得到文本 - 切 chunk - 向量化3. 图片较多的 PDFPyMuPDF 提取图片 - OCR / caption - 图片说明进入 embedding_text - 原图路径进入 metadata示例{embedding_text:登录页面截图包含用户名、密码、验证码、登录按钮。,metadata:{source:manual.pdf,page:5,image_path:/assets/page_5_image_1.png,type:image}}4. 表格较多的 PDF表格不要只当普通文本处理建议保存三份Markdown 表格给 LLM 阅读 CSV / JSON用于精确查询和计算 表格摘要参与向量检索六、Unstructured 简介Unstructured 是一个面向 LLM / RAG 的文档预处理库。它可以把 PDF、HTML、Word、PPT、图片等文件解析成结构化元素。安装pipinstallunstructured如果处理 PDF、图片和 OCR通常需要额外依赖。实际项目中可以按官方文档安装对应 extras例如 PDF、OCR、local inference 相关依赖。Unstructured 的核心思想是先 partition 成 Elements 再基于 Elements 做 chunking常见 Element 类型Element 类型含义Title标题NarrativeText正文段落ListItem列表项Table表格Image图片Header页眉Footer页脚七、Unstructured 基础用法1. 自动解析文档fromunstructured.partition.autoimportpartition elementspartition(filenamedemo.pdf)foreinelements:print(type(e).__name__,e.text[:80]ifhasattr(e,text)else)这会自动根据文件类型选择解析方式。2. 解析 PDFfromunstructured.partition.pdfimportpartition_pdf elementspartition_pdf(filenamedemo.pdf,strategyhi_res,infer_table_structureTrue,)foreinelements:print(type(e).__name__,e.text[:100])常见参数参数说明strategyfast速度快适合可复制文本 PDFstrategyhi_res使用版面分析适合复杂 PDF、扫描件、表格、标题识别infer_table_structureTrue尝试识别表格结构3. 解析图片fromunstructured.partition.imageimportpartition_image elementspartition_image(filenamepage.png,strategyhi_res,)foreinelements:print(type(e).__name__,e.text)图片解析一般依赖 OCR 和布局识别。八、Unstructured 的 Title 是怎么来的Unstructured 不是在 chunk 阶段凭空判断标题而是在 partition 阶段把文档解析成 Elements。如果某段内容被识别为Title那么chunk_by_title才能把它当作章节边界。流程如下原始文档 - partition - Title / NarrativeText / ListItem / Table 等 Elements - chunk_by_title - 按 Title 边界切 chunk九、Unstructured Chunking 用法1. 按标题切 Chunkfromunstructured.partition.pdfimportpartition_pdffromunstructured.chunking.titleimportchunk_by_title elementspartition_pdf(filenamedemo.pdf,strategyhi_res,infer_table_structureTrue,)chunkschunk_by_title(elements,max_characters1200,new_after_n_chars1000,combine_text_under_n_chars200,)forchunkinchunks:print(type(chunk).__name__)print(chunk.text[:300])参数说明参数作用max_characters单个 chunk 最大字符数new_after_n_chars超过这个长度后倾向开启新 chunkcombine_text_under_n_chars太短的 section 尽量合并2. 为什么 Unstructured 的 chunking 和普通文本切分不同普通 splitter 往往是纯文本 - 按字符数 / token 数硬切Unstructured 更像文档 - Element 结构 - 根据标题、段落、表格等结构切优势是能保留文档结构尤其适合说明书、政策文档、FAQ、操作手册。十、QA 格式文档怎么处理推荐结构{question:访问中心站需要哪些条件,answer:中心站部署...,embedding_text:问题访问中心号。,metadata:{source:中心站说明文档.pdf,page:1,section:1}}QA 数据向量化问题还是答案推荐用于检索问题 同义问题 答案摘要 关键词 用于回答完整答案不要只向量化答案也不要只保存问题。更稳的embedding_text问题如何登录中心站 同义问题中心站怎么登录登录中心站需要什么 答案摘要通过浏览器访问中心站网址输入用户名、密码和手机验证码登录。 关键词登录、网址、用户名、密码、手机验证码、验证码。十一、QA 里有图片怎么办图片不要直接塞进向量库。推荐流程图片 - OCR - caption - OCR 文本和 caption 参与向量化 - 原图路径保存到 metadata示例{type:image,path:/assets/page_2_image_1.png,caption:登录页面截图包含用户名输入框、密码输入框、发送手机验证码按钮和登录按钮。,ocr_text:用户名 密码 发送手机验证码 验证码 登录}然后把这些信息加入embedding_text图片说明登录页面截图包含用户名、密码、验证码和登录按钮。 图片 OCR用户名、密码、发送手机验证码、验证码、登录。这样用户问登录页面验证码按钮在哪里也有机会检索到正确 QA。十二、QA 里有表格怎么办表格建议不要只做 caption也不要只把表格原文混进一大段文本。推荐保存三种形态Markdown 表格给 LLM 看。 CSV / JSON用于精确查询和计算。 表格摘要参与向量检索。例如| 项目 | 最低配置 | 推荐配置 | | --- | --- | --- | | CPU | i5 | i7 / Ryzen 7 | | 内存 | 8GB | 16GB | | 显卡 | 集成显卡 | GTX 1660 |表格摘要表格说明访问中心站的硬件配置要求。最低配置为 i5、8GB 内存、集成显卡推荐配置为 i7 或 Ryzen 7、16GB 内存、GTX 1660。向量化文本可以写成问题访问中心 答案摘要需要电脑最低配置 i5、8GB 内存、集成显卡推荐 i7/Ryzen 7、16GB 内存、GTX 1660。 表格关键词CPU、内存、显卡、最低配置、推荐配置。如果用户问计算类问题推荐内存比最低内存多多少更好的做法是检索到表格 - 读取 CSV / JSON - 用程序计算 - LLM 解释结果不要完全依赖模型从自然语言表格里猜。十三、PyMuPDF 与 Unstructured 的组合方案实际项目中两者可以组合使用。方案 1Unstructured 主导适合多格式文档Unstructured partition - Elements - chunk_by_title - 表格摘要 / 图片 OCR - 向量化优点多格式统一Title、Table、ListItem 等结构清晰chunking 更贴近文档结构。缺点依赖较多复杂 PDF 的效果和环境配置有关需要检查 Title、Table 是否识别正确。方案 2PyMuPDF 主导适合 PDF 控制更细的场景PyMuPDF 按页解析 - 提取文本 / 图片 / 坐标 / 表格 - 自定义规则切 chunk - 向量化优点速度快PDF 级控制强方便保留页码、坐标、图片路径。缺点标题、段落、表格结构需要自己处理多格式支持不如 Unstructured 统一。方案 3混合方案推荐给生产项目先用 Unstructured 获取结构化 Elements 如果表格 / 图片 / 页码不满足要求 再用 PyMuPDF 做补充提取例如Unstructured 负责标题、正文、表格初步解析。 PyMuPDF 负责页面截图、图片抽取、坐标和页码补充。十四、RAG 入库数据结构推荐无论使用 PyMuPDF 还是 Unstructured最终建议统一成类似结构{id:manual_pdf_page_1_qa_1,embedding_text:问题访问中心答案摘要需要硬件、软件、网络、账号条件。关键词Windows10、Chrome、固定出口 IP、白名单、账号。,content:完整答案正文...,metadata:{source:manual.pdf,page:1,section:1,type:qa,question:访问中心站,images:[{path:/assets/page_1_image_1.png,caption:硬件条件示意图}],tables:[{path:/tables/page_1_table_1.csv,summary:硬件配置要求表}]}}向量库里主要存embedding_text metadata回答时再根据 metadata 取完整答案 Markdown 表格 图片说明 原始文件路径 页码来源十五、总结场景推荐工具推荐处理方式普通可复制 PDFPyMuPDF / Unstructured提取文本按页和标题切 chunk扫描件 PDFPyMuPDF OCR / Unstructured hi_res页面渲染或 OCR 解析多格式文档Unstructuredpartition 成 Elements再 chunk标题结构明显的文档Unstructuredchunk_by_titleQA / FAQ 文档自定义规则 Unstructured按 QA 单元入库图片多的文档PyMuPDF OCR/caption图片说明参与向量化原图保存路径表格多的文档Unstructured / PyMuPDF / pdfplumberMarkdown CSV/JSON 表格摘要需要精确页码和坐标PyMuPDF保存 page、bbox metadataPyMuPDF 和 Unstructured 在 RAG 中不是互相替代而是互补关系PyMuPDF 适合精细控制 PDF文本、图片、坐标、页面渲染、表格检测。 Unstructured 适合统一处理多格式文档Title、NarrativeText、ListItem、Table 等结构化 Elements。