转换单个文档#
整个 API 从 DocumentConverter 开始。创建它的开销很小;模型在第一次转换时加载并在之后复用,所以在整个进程中保留同一个转换器即可。
from docling.document_converter import DocumentConverter
converter = DocumentConverter()
result = converter.convert("https://arxiv.org/pdf/2408.09869") # 路径、URL 或 DocumentStream
print(result.status) # ConversionStatus.SUCCESS
doc = result.document # DoclingDocument
print(doc.export_to_markdown()[:300])convert() 返回 ConversionResult。除了 document,它还包含 status、errors、pages、timings 和 confidence(每页质量评分),可用于把低置信度的页面转给人工复核。
convert() 接受的参数#
| 参数 | 默认值 | 作用 |
|---|---|---|
source | — | Path、字符串路径或 URL,或 DocumentStream |
headers | None | source 为 URL 时使用的 HTTP 请求头(如鉴权 token) |
raises_on_error | True | 失败时抛出异常,而不是返回失败结果 |
max_num_pages | 不限 | 跳过页数超过该值的文档 |
max_file_size | 不限 | 跳过超过该字节数的文件 |
page_range | (1, ∞) | 只转换这些页,从 1 开始且包含两端,如 (1, 10) |
progress_callback | None | 接收文档、阶段和逐页的进度事件 |
签名读取自 2.143.1 中的 DocumentConverter.convert。convert_all() 接受相同参数,只是传入的是可迭代的多个来源。
从内存转换#
当文件以字节形式到达时——上传文件、S3 对象、邮件附件——用 DocumentStream 包装它。文件名的扩展名决定使用哪个后端。
from io import BytesIO
from docling.datamodel.base_models import DocumentStream
from docling.document_converter import DocumentConverter
data = open("report.pdf", "rb").read() # 或来自 S3、API 等的字节
stream = DocumentStream(name="report.pdf", stream=BytesIO(data))
doc = DocumentConverter().convert(stream).document配置 PDF 流水线#
选项按输入格式设置。对 PDF(和图片)来说,就是用 PdfFormatOption 包装一个 PdfPipelineOptions 对象:
from docling.datamodel.accelerator_options import AcceleratorOptions
from docling.datamodel.base_models import InputFormat
from docling.datamodel.pipeline_options import (
PdfPipelineOptions, TableFormerMode, TableStructureOptions,
)
from docling.document_converter import DocumentConverter, PdfFormatOption
opts = PdfPipelineOptions()
opts.do_ocr = False # 原生数字 PDF:我们测试中快 3.7 倍
opts.do_table_structure = True
opts.table_structure_options = TableStructureOptions(mode=TableFormerMode.ACCURATE)
opts.accelerator_options = AcceleratorOptions(num_threads=8, device="auto")
opts.document_timeout = 300 # 秒;超时后返回部分结果
converter = DocumentConverter(
format_options={InputFormat.PDF: PdfFormatOption(pipeline_options=opts)}
)以下是最重要的默认值,读取自 2.143.1 中 PdfPipelineOptions 的模型字段:
| 选项 | 默认值 | 说明 |
|---|---|---|
do_ocr | True | OCR 只处理没有 PDF 文本层的区域(默认模式) |
ocr_options | OcrAutoOptions() | 自动选择已安装的引擎;标准安装下为 RapidOCR |
do_table_structure | True | TableFormer 重建行、列和合并单元格 |
table_structure_options.mode | ACCURATE | 在我们的基准测试中 FAST 整体快 11% |
accelerator_options | 4 线程,device="auto" | auto 依次选择 CUDA、Apple MPS、Intel XPU、CPU |
images_scale | 1.0 | 导出的页面与图片图像的分辨率 |
generate_page_images / generate_picture_images | False | 导出图片时需要开启 |
do_formula_enrichment / do_code_enrichment | False | 公式 → LaTeX;代码块识别 |
do_picture_description / do_picture_classification | False | 用额外模型生成图片描述和图片类型 |
do_chart_extraction | False | 柱状图、饼图、折线图 → 表格 |
document_timeout | None | N 秒后停止处理该文档 |
enable_remote_services | False | 使用基于 API 的模型时必须为 True |
artifacts_path | None | 离线使用时的本地模型目录 |
OCR 引擎和语言见 OCR 指南;视觉语言流水线见 VLM 与 Granite-Docling。配置生成器可以帮你写出这些代码。
能扛住坏文件的批量转换#
convert_all() 以惰性方式逐个产出结果,处理大目录时内存占用保持平稳。设置 raises_on_error=False 后,损坏的文件会变成失败结果,而不是抛出异常。
from pathlib import Path
from docling.datamodel.base_models import ConversionStatus
from docling.document_converter import DocumentConverter
converter = DocumentConverter()
files = sorted(Path("inbox").glob("*.pdf"))
out = Path("out"); out.mkdir(exist_ok=True)
for res in converter.convert_all(files, raises_on_error=False):
name = res.input.file.stem
if res.status in (ConversionStatus.SUCCESS, ConversionStatus.PARTIAL_SUCCESS):
res.document.save_as_markdown(out / f"{name}.md")
res.document.save_as_json(out / f"{name}.json")
else:
print(f"{name}: {res.status.value}", [e.error_message for e in res.errors])2.143.1 中定义的状态有 pending、started、failure、success、partial_success 和 skipped。partial_success 通常意味着超时或某页失败——文档中仍包含成功的页面。
限制可接受的格式#
from docling.datamodel.base_models import InputFormat
from docling.document_converter import DocumentConverter
converter = DocumentConverter(
allowed_formats=[InputFormat.PDF, InputFormat.DOCX, InputFormat.PPTX]
)其他格式的文件会被拒绝而不是转换——很适合上传接口。全部 36 个 InputFormat 取值见格式页面。
DoclingDocument 的结构#
DoclingDocument 是一棵树加上若干扁平列表。每个元素都有 label、文本或数据,以及 prov(来源:页码和边界框),因此任何答案都能追溯到页面上的具体位置。
| 字段 | 内容 |
|---|---|
texts | 段落、标题、章节标题(带 level)、列表项、图注、脚注、公式、代码 |
tables | TableItem,包含单元格网格(data.num_rows、data.num_cols、合并信息) |
pictures | 图片,可选的分类与描述 |
groups | 列表、章节等容器 |
body / furniture | 正文阅读顺序树 / 页眉页脚 |
pages | 页面尺寸,以及(若生成)页面图像 |
我们转换 Docling 技术报告得到的一个真实元素:
{
"self_ref": "#/texts/2",
"label": "section_header",
"level": 1,
"text": "Version 1.0",
"prov": [{ "page_no": 1,
"bbox": { "l": 283.31, "t": 511.98, "r": 328.69, "b": 503.43,
"coord_origin": "BOTTOMLEFT" } }]
}for item, level in doc.iterate_items():
page = item.prov[0].page_no if item.prov else None
print(level, item.label, page, getattr(item, "text", "")[:60])表格转 pandas#
for i, table in enumerate(doc.tables):
df = table.export_to_dataframe(doc=doc)
print(f"table {i}: {df.shape}")
df.to_csv(f"table_{i}.csv", index=False)请传入 doc=doc:这样表格才能解析其图注和引用。在我们的测试文档中,Docling 找到 3 个表格,第一个是 4 × 8 的网格。
导出格式#
| 你需要 | 调用 |
|---|---|
| Markdown 字符串 / 文件 | doc.export_to_markdown() / doc.save_as_markdown(path) |
| 无损 JSON(可重新载入) | doc.save_as_json(path) · 用 DoclingDocument.load_from_json(path) 载入 |
| HTML | doc.export_to_html() / doc.save_as_html(path) |
| 纯文本 | doc.export_to_text() |
| Python 字典 | doc.export_to_dict() |
| YAML | doc.save_as_yaml(path) |
| DocTags(用于 VLM 训练/评测) | doc.export_to_doctags() / doc.save_as_doctags(path) |
| WebVTT(音视频字幕) | doc.export_to_vtt() / doc.save_as_vtt(path) |
| 用于 RAG 的分块 | HybridChunker().chunk(doc)——见 RAG 与分块 |
输出中的图片
Markdown、HTML 和 JSON 可以通过 image_mode 以三种方式携带图片:PLACEHOLDER(用注释标出位置,默认)、EMBEDDED(base64 内嵌)或 REFERENCED(文档旁的 PNG 文件)。图片必须在转换时生成:
from docling_core.types.doc import ImageRefMode
opts.generate_picture_images = True # 在 PdfPipelineOptions 中、转换之前设置
opts.images_scale = 2.0
...
doc.save_as_markdown("report.md", image_mode=ImageRefMode.REFERENCED)其他输入格式#
Office、HTML、Markdown 以及大多数 XML 格式根本不走 PDF 流水线:它们直接从自身结构解析,因此转换只需不到一秒,也不需要 OCR 或版面模型。图片与 PDF 走同一条流水线。音频和视频使用 ASR 流水线。各格式的详情见支持的格式。
真正有效的性能技巧#
- 原生数字 PDF 关闭 OCR——在我们的测试中提升最大(每页 8.5 → 2.3 秒)。
- 复用同一个转换器。第一次转换包含模型加载(同一份 9 页文档冷启动 27.5 秒,热启动 20.8 秒)。
- 使用
page_range,例如分类时只需要前几页。 - 设置
document_timeout,避免一个异常文件拖住整个批次。
更多数据见性能指南。
常见问题
如何用 Docling 在 Python 中把 PDF 转成 Markdown?
创建 DocumentConverter,用文件路径或 URL 调用 convert(),再调用 result.document.export_to_markdown()。对于原生数字 PDF,设置 pipeline_options.do_ocr = False 可大幅提速。
如何批量转换大量文件而不因错误中断?
使用 converter.convert_all(paths, raises_on_error=False),并检查每个 result.status,取值为 success、partial_success、failure 或 skipped。
如何把 Docling 识别的表格导出为 DataFrame?
遍历 result.document.tables,调用 table.export_to_dataframe(doc=result.document)。pandas 已随标准的 docling 包安装。
Docling 能直接转换内存中的文件吗?
可以。用 DocumentStream(name='file.pdf', stream=BytesIO(data)) 包装字节数据后传给 convert()。文件名的扩展名决定使用哪种格式。
如何限制 Docling 转换的页数?
给 convert() 传入 page_range=(1, 10),或用 max_num_pages 跳过超过页数上限的文档。
资料来源
- Docling 源码:docling/document_converter.py(2.143.1)
- Docling 源码:PdfPipelineOptions(docling/datamodel/pipeline_options.py)
- 官方文档:DoclingDocument 概念
- Docling 技术报告(arXiv 2408.09869)