請啟用 JavaScript 來查看內容

透過 Docling 輕鬆解析常見文件,匯出成 JSON、Markdown、HTML 格式

前言

去年底 (2024/11) IBM 最新開源 Docling 工具 (Python 套件),可以讀取一些常見的文件格式(PDF、DOCX、PPTX、XLSX、圖片、HTML、Markdown…)並匯出成 JSON、Markdown、HTML,以及對 PDF 裡的頁面佈局、表格、公式、程式碼…等等有較好的理解,而且也支援 OCR 辨識。

我還沒有做太多測試、比較,只是做個簡單的紀錄。



安裝套件

安裝很簡單,透過 pip 安裝:

1
pip install docling

* 本文使用 Docling 版本為:v2.17.0


使用教學 & 範例程式碼

簡單三步驟:設定來源、轉換文件、輸出結果


設定文件來源

Docling 支援多種格式:PDF、DOCX、PPTX、XLSX、Image、HTML、Markdown、AsciiDoc
參考:https://ds4sd.github.io/docling/supported_formats/

輸入可以是網址或本地檔案路徑:

1
2
3
source = "https://arxiv.org/pdf/2412.16720"  # PDF path or URL
source = "./docs/測試用.pdf"
source = "./docs/測試用2.docx"

轉換文件

將文件轉換成它定義的 DolingDocument 格式,就會包含文件的像是檔名、文字、表格、圖片…等等資訊。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 簡單快速使用
converter = DocumentConverter()

# 也可以限制轉換格式
# converter = DocumentConverter(
#     allowed_formats=[InputFormat.PDF, InputFormat.IMAGE, InputFormat.DOCX, InputFormat.PPTX, InputFormat.MD, InputFormat.HTML, InputFormat.ASCIIDOC],
#     format_options={
#         InputFormat.PDF: PdfFormatOption(
#             pipeline_cls=StandardPdfPipeline, backend=PyPdfiumDocumentBackend
#         ),
#         InputFormat.DOCX: WordFormatOption(
#             pipeline_cls=SimplePipeline  # , backend=MsWordDocumentBackend
#         ),
#     },
# )

# 預測模型會在首次使用時自動下載,也可以指定事先下載好的資料夾路徑
# 在離線環境方便使用
# 模型可能是這邊下載:https://huggingface.co/ds4sd/docling-models
# 我也不太確定
# pipeline_options = PdfPipelineOptions(artifacts_path="your location")
# converter = DocumentConverter(
#     format_options={
#         InputFormat.PDF: PdfFormatOption(pipeline_options=pipeline_options)
#     }
# )

# pipeline
# https://ds4sd.github.io/docling/usage/#adjust-pipeline-features


# 開始轉換文件
result = converter.convert(source)
# 也可以限制文件頁數和大小
# result = converter.convert(source, max_num_pages=10, max_file_size=20971520)

輸出結果

將轉換後的文件輸出成不同的格式,像是純文字、HTML、Markdown 和 JSON:

1
2
3
4
5
6
7
print(result.document.export_to_text())
print(result.document.export_to_dict())  # json
print(result.document.export_to_html())
print(result.document.export_to_markdown())
print(result.document.export_to_document_tokens())
# print(result.document.print_element_tree())
# print(result.document._export_to_indented_text(max_text_len=16))

也可以直接儲存成檔案:

1
2
3
4
5
6
7
from pathlib import Path

result.document.save_as_markdown(filename=Path("./docs/test.md"))
result.document.save_as_html(filename=Path("./docs/test.html"))
result.document.save_as_json(filename=Path("./docs/test.json"))
result.document.save_as_document_tokens(filename=Path("./docs/test.tokens"))
result.document.save_as_yaml(filename=Path("./docs/test.yaml"))

完整範例程式碼

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import json
from pathlib import Path
from docling_core.types import DoclingDocument
from docling.datamodel.base_models import InputFormat
from docling.document_converter import (
    DocumentConverter,
    PdfFormatOption,
    WordFormatOption,
)
from docling.datamodel.pipeline_options import PdfPipelineOptions
from docling.pipeline.simple_pipeline import SimplePipeline
from docling.pipeline.standard_pdf_pipeline import StandardPdfPipeline
from docling.backend.pypdfium2_backend import PyPdfiumDocumentBackend


# source = "https://arxiv.org/pdf/2408.09869"  # PDF path or URL
# source = "./docs/OpenAIo1SystemCard.pdf.pdf"
source = "./docs/測試文件.docx"

converter = DocumentConverter()
# # 可以限制轉換格式
# converter = DocumentConverter(
#     allowed_formats=[InputFormat.PDF, InputFormat.IMAGE, InputFormat.DOCX, InputFormat.PPTX, InputFormat.MD, InputFormat.HTML, InputFormat.ASCIIDOC],
#     format_options={
#         InputFormat.PDF: PdfFormatOption(
#             pipeline_cls=StandardPdfPipeline, backend=PyPdfiumDocumentBackend
#         ),
#         InputFormat.DOCX: WordFormatOption(
#             pipeline_cls=SimplePipeline  # , backend=MsWordDocumentBackend
#         ),
#     },
# )


# 開始轉換文件
result = converter.convert(source)
# 也可以限制文件頁數和大小
# result = converter.convert(source, max_num_pages=10, max_file_size=20971520)


# 輸出結果
# print(result.document.export_to_text())
print(result.document.export_to_dict())
# print(result.document.export_to_html())
# print(result.document.export_to_markdown())
# print(result.document.export_to_document_tokens())
# print(result.document.print_element_tree())
# print(result.document._export_to_indented_text(max_text_len=16))

# 直接儲存成檔案
# result.document.save_as_markdown(filename=Path("./docs/test.md"))
# result.document.save_as_html(filename=Path("./docs/test.html"))
# result.document.save_as_json(filename=Path("./docs/test.json"))
# result.document.save_as_document_tokens(filename=Path("./docs/test.tokens"))
# result.document.save_as_yaml(filename=Path("./docs/test.yaml"))


# 另一種方法,儲存與讀取
# # Save to disk
# with open('./docs/test.json', 'w', encoding='utf-8') as fp:
#     json.dump(doc.export_to_dict(), fp, ensure_ascii=False)  # use `export_to_dict` to ensure consistency

# # Load from disk
# with open('./docs/test.json', 'r', encoding='utf-8') as f:
#     doc_dict = json.load(f)
#     doc = DoclingDocument.model_validate(doc_dict)  # use standard pydantic API to populate doc

切割 chunk

另外 Docling 也內建切 chunk 的函式,在做 RAG 時會使用到:https://ds4sd.github.io/docling/examples/hybrid_chunking/

1
2
3
4
5
6
7
8
# 切 chunk
from docling.document_converter import DocumentConverter
from docling_core.transforms.chunker import HierarchicalChunker  # 分層分塊器

conv_res = DocumentConverter().convert("https://arxiv.org/pdf/2206.01062")
doc = conv_res.document
chunks = list(HierarchicalChunker().chunk(doc))
print(chunks[30])

其他

官方文件內有示範多種範例,可以探索還有哪些使用方法:https://ds4sd.github.io/docling/examples/



結語

除了 Docling,其他類似功能的套件還有像是 unstructuredMarkItDown
PyMuPDF4LLMMinerU…,我有空應該也會找時間來試試看。




參考:
Docling 官方文件
Docling GitHub
ds4sd/docling-models | Hugging Face


Embrace the unknown and embrace change. That’s where true breakthroughs happen.
擁抱未知,擁抱變化。那才是真正的突破所在!

—— 黃仁勳 (NVIDIA 共同創辦人暨執行長)


🔻 如果覺得喜歡,歡迎在下方獎勵我 5 個讚~
分享

Jia
作者
Jia
軟體工程師 - Software Engineer