CH2_01_unstructured_example
1. 创建简单示例
from unstructured.partition.auto import partition# PDF文件路径pdf_path = "../../data/C2/pdf/rag.pdf"# 使用Unstructured加载并解析PDF文档elements = partition( filename=pdf_path, content_type="application/pdf")# 打印解析结果print(f"解析完成: {len(elements)} 个元素, {sum(len(str(e)) for e in elements)} 字符")输出为:
解析完成: 279 个元素, 7500 字符partition 函数参数解析:
filename: 文档文件路径,支持本地文件路径;content_type: 可选参数,指定MIME类型(如”application/pdf”),可绕过自动文件类型检测;file: 可选参数,文件对象,与 filename 二选一使用;url: 可选参数,远程文档 URL,支持直接处理网络文档;include_page_breaks: 布尔值,是否在输出中包含页面分隔符;strategy: 处理策略,可选 “auto”、“fast”、“hi_res” 等;auto:优先尝试快速提取文本,如果文本提取效果差就自动降级为 OCR.fast:直接用 PDF 解析器提取 内置文本层,速度快,但不解析图片中的文字;hi_res:高精度模式,先做 OCR,然后再结合布局分析,精度最高;ocr_only:完全忽略 PDF 内置文本层,只靠 OCR 识别所有内容。
encoding: 文本编码格式,默认自动检测。
partition 函数使用自动文件类型检测,内部会根据文件类型路由到对应的专用函数(如 PDF 文件会调用partition_pdf)。如果需要更专业的 PDF 处理,可以直接使用 from unstructured.partition.pdf import partition_pdf,它提供更多 PDF 特有的参数选项,如 OCR 语言设置、图像提取、表格结构推理等高级功能,同时性能更优。
在实际应用中,针对 pdf 的处理,目前更多选用的是 PaddleOCR、MinerU 等模型或工具。
# 统计元素类型from collections import Countertypes = Counter(e.category for e in elements)print(f"元素类型: {dict(types)}")输出为:
元素类型: {'Header': 22, 'Title': 195, 'UncategorizedText': 41, 'NarrativeText': 3, 'Footer': 15, 'ListItem': 3}# 显示所有元素print("\n所有元素:")for i, element in enumerate(elements, 1): print(f"Element {i} ({element.category}):") print(element) print("=" * 60)输出为:
所有元素:Element 1 (Header):网页============================================================Element 2 (Header):新闻============================================================Element 3 (Header):贴吧============================================================Element 4 (Header):知道============================================================Element 5 (Header):网盘============================================================Element 6 (Header):图片============================================================Element 7 (Header):视频============================================================Element 8 (Header):地图...============================================================Element 279 (Footer):HTML to PDF============================================================2. 用 partition_pdf 替换当前 partition 函数
我们使用 partition_pdf 替换当前 partition 函数并分别尝试用 hi_res 和 ocr_only 进行解析,观察输出结果有何变化。
from unstructured.partition.pdf import partition_pdf# 运行前确保安装 Poppler 和 Tesseract OCRelements = partition_pdf( filename=pdf_path, content_type="application/pdf", strategy = "ocr_only")# 打印解析结果print(f"解析完成: {len(elements)} 个元素, {sum(len(str(e)) for e in elements)} 字符")输出为:
# hi_res 结果解析完成: 221 个元素, 8265 字符
# ocr_only 结果解析完成: 137 个元素, 8282 字符关于元素数量,一般而言是越少越好:
| 策略 | 元素数 | 原因 |
|---|---|---|
fast | 279(最多) | 直接读 PDF 文本层,PDF 里每个独立文本对象(哪怕只是”网页”两个字)都算一个元素 |
hi_res | 221 | 布局模型会把相邻小文本合并到同一区域,所以元素更少,但结构更合理 |
ocr_only | 137(最少) | 每页是一大块文字 + 标题,碎片化程度最低 |
fast 的 279 个元素中,有 195 个 Title,很多只是导航栏的碎片(“网页”、“新闻”、“贴吧”……)。hi_res 的布局模型将这些碎片合并成了更大的块。
# 统计元素类型from collections import Countertypes = Counter(e.category for e in elements)print(f"元素类型: {dict(types)}")输出为:
# hi_res 结果元素类型: {'Image': 22, 'UncategorizedText': 85, 'Header': 4, 'NarrativeText': 68, 'Table': 4, 'FigureCaption': 4, 'Title': 30, 'ListItem': 4}
# ocr_only 结果元素类型: {'UncategorizedText': 54, 'Title': 55, 'NarrativeText': 27, 'ListItem': 1}可以看到,在输出的元素类型上,两种策略有很大不同:
| 类型 | hi_res | ocr_only | 原因 |
|---|---|---|---|
Image | ✅ 22 | ❌ 无 | hi_res 有布局检测模型,能识别图片区域;ocr_only 只做 OCR,不分析布局 |
Table | ✅ 4 | ❌ 无 | 同上,表格区域由布局模型识别 |
FigureCaption | ✅ 4 | ❌ 无 | 图片/表格的标题,也只有布局模型能识别 |
Header | ✅ 4 | ❌ 无 | 页面顶部导航栏等 |
NarrativeText | 68 | 27 | hi_res 中布局模型区分了正文和杂项,ocr_only 很多被归入 UncategorizedText |
UncategorizedText | 85 | 54 | ocr_only 没有布局信息,大量文本无法归类 |
Title | 30 | 55 | ocr_only 中 OCR 识别的短文本片段容易被判为 Title |
这主要是由于两种策略不同的流程导致的:
hi_res 流程: PDF → Poppler 转图片 → 布局检测模型(YOLOX)识区域 → Tesseract OCR 各区域 ↓ Image / Table / Header NarrativeText / Title ...
ocr_only 流程: PDF → Poppler 转图片 → Tesseract OCR 整页 → 全是文字,无布局标签可以看到,hi_res 多了一个 布局检测步骤,所以可以区分出 image, table, figure caption 等结构化元素。
# 显示所有元素print("\n所有元素:")for i, element in enumerate(elements, 1): print(f"Element {i} ({element.category}):") print(element) print("=" * 60)输出为:
# hi_res 结果所有元素:Element 1 (Image):
============================================================Element 2 (UncategorizedText):Bh fe============================================================Element 3 (UncategorizedText):Se «6 Be BR 8H Me OE 6B CR OBS============================================================Element 4 (Header):百度首页 登录 注册============================================================Element 5 (UncategorizedText):0 0 Bai @ Bil | eme22n============================================================Element 6 (UncategorizedText):x============================================================Element 7 (UncategorizedText):进⼊词条============================================================Element 8 (UncategorizedText):全站搜索...============================================================Element 221 (UncategorizedText):HTML to PDF============================================================
# ocr_only 结果所有元素:Element 1 (UncategorizedText):Bh fe Se «6 Be BR 8H Me OE 6B CR OBS ESR SR ith============================================================Element 2 (Title):0 0 Bai @ Bil | eme22n x SME | mm============================================================Element 3 (NarrativeText):MBA RAATEABEBANEAAR, VRE A BIDHAE RR O, CEL IERAA: BREN RRMA, ONCE CIRS, LYSE! iFIB>> Bn pias HEAR ALIAS a MAB BAAR RAE > 1 REA i oa E AK ) HR Otte Lew============================================================Element 4 (UncategorizedText):ABB AWARAZ—============================================================Element 5 (Title):MoingSh============================================================Element 6 (NarrativeText):fomieas tat OACe >)============================================================Element 7 (NarrativeText):it =============================================================Element 8 (Title):[= = HEhH - SAR RAGFlow RAF RAMA...============================================================Element 137 (UncategorizedText):Explore our developer-friendly HTML to PDF API Printed using PDFCrowd H to PDF============================================================从具体识别到的元素来看,我们可以发现 ocr_only 对中文的效果很差,比如 Bh, fe 等完全就是乱码,甚至英文部分的 MBA, RAATEABEBANEAAR 也严重变形。
这主要是 tesseract 默认使用英文语言包导致的,所以对于我们的示例(中文 PDF),tesseract 几乎无法正确识别。
对此,我们可以添加 language 参数(记得下载 tesseract 的中文语言包):
elements = partition_pdf( filename=pdf_path, strategy="ocr_only", # ocr_only, hi_res languages=["chi_sim"] # 简体中文)增加语言包后的输出为:
# hi_res 的结果解析完成: 241 个元素, 8224 字符
# ocr_only 的结果解析完成: 143 个元素, 12247 字符首先我们来关注 hi_res 的变化。中文包让 OCR 能在布局模型划分的区域内识别出更多独立文本块,所以元素数略微增加。之前因乱码被合并或丢弃的文本现在被正确提取。而字符数反而有所减少,这是因为 OCR 正确识别中文后,同一个面积的区域内,中文字符比英文乱码字符更少(一个汉字 vs 一串”Xe «6 Be BR…”),所以总数反而略降。
可以看到,在加装了中文语言包后,ocr_only 解析出的字符几乎暴涨了 50%,从 8282 -> 12247. 这是因为英文 OCR 时,中文段落被识别为一堆乱码字符,很多”字”根本没被识别出来。中文包生效后,每个汉字都被正确识别,所以总字符数大幅增加。
# hi_res 的结果元素类型: {'Image': 21, 'UncategorizedText': 106, 'Header': 4, 'NarrativeText': 68, 'Table': 4, 'FigureCaption': 4, 'Title': 30, 'ListItem': 4}
# ocr_only 的结果元素类型: {'Title': 52, 'NarrativeText': 27, 'UncategorizedText': 54, 'ListItem': 10}hi_res 的 UncategorizedText 有所增加,这些新增的 UncategorizedText 主要来自导航栏碎片——之前因为乱码被丢弃或归为其他类型,现在被正确识别并保留。
在加装中文语言包后,ocr_only 也成功识别出了更多的结构化信息,例如列表项(ListItem 1 -> 10),之前因为乱码而根本无法判定。
# hi_res 的结果所有元素:Element 1 (Image):
============================================================Element 2 (UncategorizedText):国 页============================================================Element 3 (UncategorizedText):新 闻 _============================================================Element 4 (UncategorizedText):吧============================================================Element 5 (UncategorizedText):贴吧============================================================Element 6 (UncategorizedText):知 道============================================================Element 7 (UncategorizedText):网盘============================================================Element 8 (UncategorizedText):图片...============================================================Element 241 (UncategorizedText):HTML to PDF============================================================
# ocr_only 的结果所有元素:Element 1 (Title):国 页 新 闻 _ 贴 吧 知 道============================================================Element 2 (Title):百 科 百 度 首 页 “ 登 录 “ 注 册============================================================Element 3 (Title):.... Baidb 百 租 | 8458 办 x============================================================Element 4 (Title):全 站 搜 索 ‖ 帝 助============================================================Element 5 (NarrativeText):近 期 有 不 法 分 子 冒 兆 百 度 百 科 客 方 人 员 , 以 删 除 词 条 为 申 姚 防 并 敌 许 关 企 业 , 在 此 严 正 声 明 : 百 度 百 科 是 免 资 缉 辑 平 台 , 绝 不 存 在 收 费 代 编 服 务 , 请 勿 上 当 受 腾 ! 详 情 >>============================================================Element 6 (UncategorizedText):首 页 秒 懂 百 科 特 色 百 科 知 识 专 题 加 入 百 科 百 科 团 队 权 威 合 作============================================================Element 7 (Title):《 索 增 强 生 成 。m============================================================Element 8 (Title):大 模 型 前 治 技 术 之 一...============================================================Element 143 (NarrativeText):Printed using PDFCrowd H to PDF============================================================hi_res 在实际解析出的元素上变化不大,因为 hi_res 的元素类型靠的是布局模型(YOLOX),语言包只影响 OCR 文字质量,不影响区域检测,所以类型分布变化不大。
可以很明显地看出,加装了中文语言包后,ocr_only 实际解析出的内容从天书变成了可读的中文。
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!