# Document Parser 使用说明 模块化文档解析器,将 DOCX、PPTX、XLSX、PDF 文件转换为 Markdown 格式。 每种文档类型配备多个解析器,按优先级依次尝试,前一个失败自动回退到下一个。不安装任何第三方库时,DOCX/PPTX/XLSX 仍可通过内置 XML 原生解析工作(PDF 至少需要 pypdf)。 ## 快速开始 ```bash # 最简运行(XML 原生解析,无需安装依赖) python parser.py report.docx # 安装推荐依赖后运行 pip install "markitdown[docx]" python parser.py report.docx # 使用 uv 一键运行(自动安装依赖,无需手动 pip install) uv run --with "markitdown[docx]" parser.py report.docx ``` ## 命令行用法 ### 基本语法 ```bash python parser.py [options] ``` `file_path` 为 DOCX、PPTX、XLSX 或 PDF 文件路径(相对或绝对路径)。不带任何选项时输出完整 Markdown 内容。 ### 参数说明 以下参数互斥,一次只能使用一个: | 短选项 | 长选项 | 说明 | |--------|--------|------| | `-c` | `--count` | 输出解析后文档的总字符数(不含换行符) | | `-l` | `--lines` | 输出解析后文档的总行数 | | `-t` | `--titles` | 输出所有标题行(1-6 级,含 `#` 前缀) | | `-tc ` | `--title-content ` | 提取指定标题及其下级内容(`name` 不包含 `#` 号) | | `-s ` | `--search ` | 使用正则表达式搜索文档,返回匹配结果 | 搜索辅助参数(与 `-s` 配合使用): | 短选项 | 长选项 | 说明 | |--------|--------|------| | `-n ` | `--context ` | 每个匹配结果包含的前后非空行数(默认:2) | PDF 专用参数: | 长选项 | 说明 | |--------|------| | `--high-res` | 启用 OCR 版面分析(需要额外依赖,处理较慢) | ### 退出码 | 退出码 | 含义 | |--------|------| | `0` | 解析成功 | | `1` | 错误(文件不存在、格式无效、所有解析器失败、标题未找到、正则无效或无匹配) | ### 使用示例 **输出完整 Markdown:** ```bash python parser.py report.docx # 输出到终端 python parser.py report.docx > output.md # 重定向到文件 ``` **统计信息(`-c` / `-l`):** 输出单个数字,适合管道处理。 ```bash $ python parser.py report.docx -c 8500 $ python parser.py report.docx -l 215 ``` **提取标题(`-t`):** 每行一个标题,保留 `#` 前缀和层级。PDF 通常不包含语义化标题层级。 ```bash $ python parser.py report.docx -t # 第一章 概述 ## 1.1 背景 ## 1.2 目标 # 第二章 实现 ``` **提取标题内容(`-tc`):** 输出指定标题及其下级内容。如果文档中有多个同名标题,用 `---` 分隔。每段输出包含上级标题链。 ```bash $ python parser.py report.docx -tc "1.1 背景" # 第一章 概述 ## 1.1 背景 这是背景的详细内容... ``` **搜索(`-s`):** 支持 Python 正则表达式语法。多个匹配结果用 `---` 分隔。`-n` 控制上下文行数。 ```bash $ python parser.py report.docx -s "测试" -n 1 上一行内容 包含**测试**关键词的行 下一行内容 --- 另一处上一行 另一处**测试**内容 另一处下一行 ``` ### 批量处理 ```bash # Linux/Mac for file in *.docx; do python parser.py "$file" > "${file%.docx}.md" done # Windows PowerShell Get-ChildItem *.docx | ForEach-Object { python parser.py $_.FullName > ($_.BaseName + ".md") } ``` ### 管道使用 ```bash # 过滤包含关键词的行 python parser.py report.docx | grep "重要" > important.md # 统计含表格行数 python parser.py data.xlsx | grep -c "^|" ``` ## 安装 脚本基于 Python 3.6+ 运行。每种文档类型有多个解析器按优先级依次尝试,建议安装对应类型的**所有**依赖以获得最佳兼容性。也可以只安装部分依赖,脚本会自动选择可用的解析器。 ### DOCX 优先级:Docling → unstructured → pypandoc-binary → MarkItDown → python-docx → XML 原生 ```bash # pip pip install docling "unstructured[docx]" markdownify pypandoc-binary "markitdown[docx]" python-docx # uv(一键运行,无需预安装) uv run --with docling --with "unstructured[docx]" --with markdownify --with pypandoc-binary --with "markitdown[docx]" --with python-docx parser.py report.docx ``` ### PPTX 优先级:Docling → unstructured → MarkItDown → python-pptx → XML 原生 ```bash # pip pip install docling "unstructured[pptx]" markdownify "markitdown[pptx]" python-pptx # uv uv run --with docling --with "unstructured[pptx]" --with markdownify --with "markitdown[pptx]" --with python-pptx parser.py presentation.pptx ``` ### XLSX 优先级:Docling → unstructured → MarkItDown → pandas → XML 原生 ```bash # pip pip install docling "unstructured[xlsx]" markdownify "markitdown[xlsx]" pandas tabulate # uv uv run --with docling --with "unstructured[xlsx]" --with markdownify --with "markitdown[xlsx]" --with pandas --with tabulate parser.py data.xlsx ``` ### PDF 默认优先级:Docling → unstructured (fast) → MarkItDown → pypdf `--high-res` 优先级:Docling OCR → unstructured OCR (hi_res) → Docling → unstructured (fast) → MarkItDown → pypdf > **平台差异说明**:`--high-res` 模式在不同平台上需要不同的依赖配置,详见下方各平台说明。 #### Windows x86_64 ```bash # pip - 基础文本提取(fast 策略,无需 OCR) pip install docling "unstructured[pdf]" markdownify "markitdown[pdf]" pypdf # pip - OCR 版面分析(--high-res 所需依赖) pip install docling "unstructured[pdf]" unstructured-paddleocr "paddlepaddle==2.6.2" ml-dtypes markdownify "markitdown[pdf]" pypdf # uv - 基础文本提取 uv run --with docling --with "unstructured[pdf]" --with markdownify --with "markitdown[pdf]" --with pypdf parser.py report.pdf # uv - OCR 版面分析 uv run --with docling --with "unstructured[pdf]" --with unstructured-paddleocr --with "paddlepaddle==2.6.2" --with ml-dtypes --with markdownify --with "markitdown[pdf]" --with pypdf parser.py report.pdf --high-res ``` > **Windows 说明**:hi_res 策略需要额外安装 `unstructured-paddleocr`、`paddlepaddle==2.6.2`、`ml-dtypes`。PaddlePaddle 必须锁定 2.x 版本,3.x 在 Windows 上有 OneDNN 兼容问题。 #### macOS x86_64 (Intel) macOS x86_64 上 `docling-parse` 5.x 没有预编译 wheel,需要使用 4.0.0 版本;同时 `easyocr` 与 NumPy 2.x 不兼容,需要锁定 `numpy<2`。 ```bash # uv - 基础文本提取 uv run --python 3.12 --with "docling==2.40.0" --with "docling-parse==4.0.0" --with "numpy<2" --with "markitdown[pdf]" --with pypdf parser.py report.pdf # uv - OCR 版面分析(--high-res) uv run --python 3.12 --with "docling==2.40.0" --with "docling-parse==4.0.0" --with "numpy<2" --with "markitdown[pdf]" --with pypdf parser.py report.pdf --high-res ``` > **macOS x86_64 说明**: > - 必须指定 `--python 3.12`(PaddlePaddle 不支持 Python 3.14) > - `docling==2.40.0` 兼容 `docling-parse==4.0.0`(唯一有 x86_64 预编译 wheel 的版本) > - `numpy<2` 避免 easyocr 与 NumPy 2.x 的兼容性问题 > - Docling 在 macOS 上使用 EasyOCR 作为 OCR 后端,无需安装 PaddleOCR #### macOS arm64 (Apple Silicon) / Linux ```bash # uv - 基础文本提取 uv run --with docling --with "unstructured[pdf]" --with markdownify --with "markitdown[pdf]" --with pypdf parser.py report.pdf # uv - OCR 版面分析 uv run --with docling --with "unstructured[pdf]" --with markdownify --with "markitdown[pdf]" --with pypdf parser.py report.pdf --high-res ``` > **通用说明**:PDF 无内置 XML 原生解析,至少需要安装 pypdf。默认模式下 Docling 不启用 OCR,unstructured 使用 fast 策略。指定 `--high-res` 后,Docling 启用 OCR。 ### 安装所有依赖 #### Windows x86_64 ```bash # pip - 基础文本提取(不包含 PDF OCR) pip install docling "unstructured[docx,pptx,xlsx,pdf]" markdownify pypandoc-binary "markitdown[docx,pptx,xlsx]" python-docx python-pptx pandas tabulate pypdf # pip - 完整版(包含 PDF OCR) pip install docling "unstructured[docx,pptx,xlsx,pdf]" markdownify unstructured-paddleocr "paddlepaddle==2.6.2" ml-dtypes pypandoc-binary "markitdown[docx,pptx,xlsx,pdf]" python-docx python-pptx pandas tabulate pypdf # uv - 基础文本提取 uv run --with docling --with "unstructured[docx,pptx,xlsx,pdf]" --with markdownify --with pypandoc-binary --with "markitdown[docx,pptx,xlsx]" --with python-docx --with python-pptx --with pandas --with tabulate --with pypdf parser.py file.docx # uv - 完整版(包含 PDF OCR) uv run --with docling --with "unstructured[docx,pptx,xlsx,pdf]" --with markdownify --with unstructured-paddleocr --with "paddlepaddle==2.6.2" --with ml-dtypes --with pypandoc-binary --with "markitdown[docx,pptx,xlsx,pdf]" --with python-docx --with python-pptx --with pandas --with tabulate --with pypdf parser.py file.docx ``` #### macOS x86_64 (Intel) ```bash # uv - 完整版(包含 PDF OCR) uv run --python 3.12 --with "docling==2.40.0" --with "docling-parse==4.0.0" --with "numpy<2" --with "markitdown[docx,pptx,xlsx,pdf]" --with pypandoc-binary --with python-docx --with python-pptx --with pandas --with tabulate --with pypdf parser.py file.docx ``` > macOS x86_64 上由于依赖兼容性问题,无法使用 unstructured,但 docling 可以处理所有格式。 #### macOS arm64 (Apple Silicon) / Linux ```bash # uv - 基础文本提取 uv run --with docling --with "unstructured[docx,pptx,xlsx,pdf]" --with markdownify --with pypandoc-binary --with "markitdown[docx,pptx,xlsx]" --with python-docx --with python-pptx --with pandas --with tabulate --with pypdf parser.py file.docx # uv - 完整版(包含 PDF OCR) uv run --with docling --with "unstructured[docx,pptx,xlsx,pdf]" --with markdownify --with pypandoc-binary --with "markitdown[docx,pptx,xlsx,pdf]" --with python-docx --with python-pptx --with pandas --with tabulate --with pypdf parser.py file.docx ``` ### 依赖说明 **MarkItDown**:需要按文档类型安装可选依赖,直接 `pip install markitdown` 不包含任何格式支持。 ```bash pip install "markitdown[docx]" # DOCX pip install "markitdown[pptx]" # PPTX pip install "markitdown[xlsx]" # XLSX pip install "markitdown[pdf]" # PDF pip install "markitdown[docx,pptx,xlsx,pdf]" # 全部 ``` **Docling**:DOCX/PPTX/XLSX 使用 SimplePipeline 直接解析 XML 结构,不涉及 OCR。PDF 默认不启用 OCR(`do_ocr=False`),指定 `--high-res` 后启用 OCR(`do_ocr=True`)。首次运行 OCR 模式会自动下载模型到缓存目录,需保持网络连通。 **unstructured**:需同时安装 `markdownify`。支持按文档类型安装特定 extras 以减少依赖量: - `unstructured[docx]` - DOCX 处理(仅需 `python-docx`) - `unstructured[pptx]` - PPTX 处理(仅需 `python-pptx`) - `unstructured[xlsx]` - XLSX 处理(需 `openpyxl`、`xlrd`、`pandas` 等) - `unstructured` - 基础包(用于 PDF fast 策略) - `unstructured[all-docs]` - 所有文档类型(包含大量不必要的 OCR/视觉依赖) **PaddleOCR**:不能用 `paddleocr` 代替 `unstructured-paddleocr`,unstructured 查找的模块名是 `unstructured_paddleocr`。 ## 输出格式 ### Markdown 文档结构 无选项时输出完整 Markdown,包含以下元素: ```markdown # 一级标题 正文段落 ## 二级标题 - 无序列表项 - 无序列表项 1. 有序列表项 2. 有序列表项 | 列1 | 列2 | 列3 | |------|------|------| | 数据1 | 数据2 | 数据3 | **粗体** *斜体* 下划线 ``` ### 各格式特有结构 **PPTX** — 每张幻灯片以 `## Slide N` 为标题,幻灯片之间以 `---` 分隔: ```markdown ## Slide 1 幻灯片 1 的内容 --- ## Slide 2 幻灯片 2 的内容 --- ``` **XLSX** — 以 `## SheetName` 区分工作表,数据以 Markdown 表格呈现: ```markdown # Excel数据转换结果 (原生XML解析) ## Sheet1 | 列1 | 列2 | 列3 | |------|------|------| | 数据1 | 数据2 | 数据3 | ## Sheet2 | 列A | 列B | |------|------| | 值1 | 值2 | ``` **PDF** — 纯文本流,通常不包含语义化标题层级(PDF 是版面描述格式,标题只是视觉样式)。使用 Docling 或 unstructured hi_res 策略可通过版面分析识别部分标题,但准确度取决于排版质量。 ### 内容自动处理 输出前会自动进行以下处理: | 处理 | 说明 | |------|------| | 图片移除 | 删除 `![alt](url)` 语法 | | 空行规范化 | 连续多个空行合并为一个 | | RGB 噪声过滤 | 移除 `R:255 G:128 B:0` 格式的颜色值行(仅 unstructured 解析器) | | 页码噪声过滤 | 移除 `— 3 —` 格式的页码行(仅 unstructured 解析器) | | 页眉/页脚过滤 | 自动跳过 Header/Footer 元素(仅 unstructured 解析器) | ## 错误处理 ### 错误消息 ```bash # 文件不存在 $ python parser.py missing.docx 错误: 文件不存在: missing.docx # 格式无效 $ python parser.py readme.txt 错误: 不是有效的 DOCX、PPTX、XLSX 或 PDF 格式: readme.txt # 所有解析器失败(DOCX 示例) $ python parser.py report.docx 所有解析方法均失败: - Docling: docling 库未安装 - unstructured: unstructured 库未安装 - pypandoc-binary: pypandoc-binary 库未安装 - MarkItDown: MarkItDown 库未安装 - python-docx: python-docx 库未安装 - XML 原生解析: document.xml 不存在或无法访问 # 标题未找到 $ python parser.py report.docx -tc "不存在的标题" 错误: 未找到标题 '不存在的标题' # 无效正则或无匹配 $ python parser.py report.docx -s "[invalid" 错误: 正则表达式无效或未找到匹配: '[invalid' ``` ### 解析器回退机制 脚本按优先级依次尝试各解析器。每个解析器失败后记录原因(库未安装 / 解析失败 / 文档为空),然后自动尝试下一个。全部失败时输出汇总信息并以退出码 1 退出。 ## 解析器对比 ### DOCX | 解析器 | 优点 | 缺点 | 适用场景 | |---------|------|--------|---------| | **Docling** | 单一依赖覆盖全格式;自动 OCR;输出结构稳定 | 首次需下载模型;内存占用较高 | 一键解析;需要 OCR | | **unstructured** | 元素类型感知;自动过滤噪声;HTML 表格转 Markdown | 需 `unstructured[docx]` / `[pptx]` / `[xlsx]` + `markdownify` | 结构化输出;表格转换 | | **pypandoc-binary** | 自带 Pandoc;输出整洁;错误信息清晰 | 仅 DOCX;包体积大 | 标准化 Markdown | | **MarkItDown** | 微软官方;格式规范 | 输出简洁 | 标准格式;自动化处理 | | **python-docx** | 输出最详细;保留完整结构;支持复杂样式 | 可能含多余空行 | 精确控制输出 | | **XML 原生** | 无需依赖;速度快 | 样式处理有限 | 依赖不可用时兜底 | ### PPTX | 解析器 | 优点 | 缺点 | 适用场景 | |---------|------|--------|---------| | **Docling** | 文本/表格/图片 OCR;统一 Markdown | 需下载模型 | 一次性转换;含图片的 PPTX | | **unstructured** | 元素感知;过滤 RGB 噪声;表格转换 | 需 `unstructured[pptx]` + `markdownify` | 结构化输出 | | **MarkItDown** | 自动 Slide 分隔;简洁 | 详细度低 | 快速预览 | | **python-pptx** | 输出最详细;支持层级列表 | 依赖私有 API | 完整内容提取 | | **XML 原生** | 无需依赖;速度快 | 分组简单 | 依赖不可用时兜底 | ### XLSX | 解析器 | 优点 | 缺点 | 适用场景 | |---------|------|--------|---------| | **Docling** | 全表导出;处理合并单元格/图像 OCR | 大表可能慢 | 快速全表转换 | | **unstructured** | 元素感知;过滤噪声;表格转换 | 需 `unstructured[xlsx]` + `markdownify` | 结构化输出 | | **MarkItDown** | 支持多工作表;简洁 | 详细度低 | 快速预览 | | **pandas** | 功能强大;支持复杂表格 | 需 `pandas` + `tabulate` | 数据分析 | | **XML 原生** | 无需依赖;支持所有单元格类型 | 无数据处理能力 | 依赖不可用时兜底 | ### PDF | 解析器 | 模式 | 优点 | 缺点 | 适用场景 | |---------|------|------|--------|---------| | **Docling** | 默认 | 结构化 Markdown;表格/图片占位 | 首次需下载模型 | 有文本层的 PDF | | **Docling OCR** | `--high-res` | 内置 OCR;结构化 Markdown | 模型体积大;OCR 耗时长 | 扫描版 PDF;多语言 | | **unstructured** | 默认 | fast 策略;速度快 | 不做版面分析;标题不可靠 | 快速文本提取 | | **unstructured OCR** | `--high-res` | hi_res 版面分析 + PaddleOCR;标题识别 | 需额外 PaddleOCR 依赖 | 版面分析;OCR | | **MarkItDown** | 通用 | 微软官方;格式规范 | 输出简洁 | 标准格式 | | **pypdf** | 通用 | 轻量;速度快;安装简单 | 功能简单 | 快速文本提取 | ## 常见问题 ### 为什么有些内容没有提取到? 不同解析器输出详细度不同。优先级高的解析器不一定输出最详细——Docling 和 unstructured 侧重结构化,python-docx/python-pptx 输出最详细但不做噪声过滤。建议安装对应类型的所有依赖,脚本会自动选择优先级最高的可用解析器。 ### PDF 文件没有标题层级? PDF 是版面描述格式,不包含语义化标题结构。使用 `--high-res` 参数可启用 Docling OCR 或 unstructured hi_res 策略,通过版面分析识别部分标题,准确度取决于排版质量。默认模式下建议用 `-s` 搜索定位内容,或用 `-c` / `-l` 了解文档规模。 ### 表格格式不正确? XML 原生解析器对复杂表格(合并单元格、嵌套表格)支持有限。安装 Docling、unstructured 或对应的专用库可获得更好的表格处理效果。 ### 中文显示乱码? 脚本输出 UTF-8 编码,确保终端支持: ```bash # Linux/Mac export LANG=en_US.UTF-8 # Windows PowerShell [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 ``` ### 如何只使用特定解析器? 当前版本不支持指定解析器,总是按优先级自动选择。可以通过只安装目标解析器的依赖来间接控制——未安装的解析器会被跳过。 ### 大文件处理慢? Docling 和 unstructured 对大文件较慢(尤其是 OCR)。如果只需要快速提取文本,可以只安装轻量依赖(如 pypdf、python-docx),让脚本回退到这些解析器。DOCX/PPTX/XLSX 不安装任何依赖时使用 XML 原生解析,速度最快。 ## 文件结构 ``` scripts/ ├── common.py # 公共函数和常量 ├── docx_parser.py # DOCX 文件解析 ├── pptx_parser.py # PPTX 文件解析 ├── xlsx_parser.py # XLSX 文件解析 ├── pdf_parser.py # PDF 文件解析 ├── parser.py # 命令行入口 └── README.md # 本文档 ```