1 · PDF を Markdown に、画像はファイルとして保存#
from pathlib import Path
from docling.datamodel.base_models import InputFormat
from docling.datamodel.pipeline_options import PdfPipelineOptions
from docling.document_converter import DocumentConverter, PdfFormatOption
from docling_core.types.doc import ImageRefMode
opts = PdfPipelineOptions(do_ocr=False, generate_picture_images=True, images_scale=2.0)
converter = DocumentConverter(format_options={InputFormat.PDF: PdfFormatOption(pipeline_options=opts)})
doc = converter.convert("report.pdf").document
out = Path("out"); out.mkdir(exist_ok=True)
doc.save_as_markdown(out / "report.md", artifacts_dir=Path("images"), image_mode=ImageRefMode.REFERENCED)
print(sorted(p.name for p in (out / "images").glob("*.png"))[:3])画像は out/images に PNG として書き出され、Markdown から相対パスでリンクされます。相対パスの artifacts_dir は Markdown ファイルのフォルダを基準に解決されます。省略してサブフォルダに保存すると、docling-core 2.106.0 では画像が 1 段深く(out/out/report_artifacts)入れ子になり、テストで驚かされました。
2 · フォルダ全体を変換し、壊れたファイルを飛ばし、レポートを書く#
import csv
from pathlib import Path
from docling.datamodel.base_models import ConversionStatus
from docling.document_converter import DocumentConverter
src, out = Path("inbox"), Path("out")
out.mkdir(exist_ok=True)
converter = DocumentConverter()
with open(out / "report.csv", "w", newline="") as f:
log = csv.writer(f)
log.writerow(["file", "status", "pages", "seconds"])
files = [p for p in src.iterdir() if p.is_file()]
for res in converter.convert_all(files, raises_on_error=False):
name = res.input.file.name
if res.status in (ConversionStatus.SUCCESS, ConversionStatus.PARTIAL_SUCCESS):
res.document.save_as_markdown(out / f"{res.input.file.stem}.md")
secs = sum(sum(t.times) for k, t in res.timings.items() if k == "pipeline_total")
log.writerow([name, res.status.value, len(res.pages), round(secs, 1)])pipeline_total はプロファイリングが有効(settings.debug.profile_pipeline_timings = True)なときだけ入ります。それ以外では秒数の列は 0 です。
3 · すべての表を CSV と 1 つの Excel ブックに#
import pandas as pd
from docling.document_converter import DocumentConverter
doc = DocumentConverter().convert("report.pdf").document
with pd.ExcelWriter("tables.xlsx") as xls:
for i, table in enumerate(doc.tables, start=1):
df = table.export_to_dataframe(doc=doc)
df.to_csv(f"table_{i}.csv", index=False)
df.to_excel(xls, sheet_name=f"table_{i}", index=False)
print(i, df.shape, "page", table.prov[0].page_no)pandas が .xlsx の書き込みに使う openpyxl は Docling と一緒にインストールされます。
4 · ページごとに 1 つの Markdown ファイル#
from docling.document_converter import DocumentConverter
doc = DocumentConverter().convert("report.pdf").document
for page_no in sorted(doc.pages):
md = doc.export_to_markdown(page_no=page_no)
with open(f"page_{page_no:03d}.md", "w") as f:
f.write(md)
print(len(doc.pages), "pages written")5 · 人の確認が必要なページを見つける#
各 ConversionResult には信頼度レポートが付きます。ページごとの解析・レイアウト・表・OCR のスコアと、総合評価(poor・fair・good・excellent)です。
from docling.document_converter import DocumentConverter
res = DocumentConverter().convert("report.pdf")
conf = res.confidence
print("document:", conf.mean_grade.value, round(conf.mean_score, 3))
for page_no, scores in sorted(conf.pages.items()):
print(page_no, scores.mean_grade.value, round(scores.layout_score, 3))6 · 図とキャプションを書き出す#
from docling.datamodel.base_models import InputFormat
from docling.datamodel.pipeline_options import PdfPipelineOptions
from docling.document_converter import DocumentConverter, PdfFormatOption
opts = PdfPipelineOptions(do_ocr=False, generate_picture_images=True, images_scale=2.0)
conv = DocumentConverter(format_options={InputFormat.PDF: PdfFormatOption(pipeline_options=opts)})
doc = conv.convert("report.pdf").document
for i, pic in enumerate(doc.pictures, start=1):
img = pic.get_image(doc)
if img is not None:
img.save(f"figure_{i}.png")
print(i, pic.prov[0].page_no, pic.caption_text(doc)[:70])7 · バイト列を変換(S3、アップロード、メール添付)#
from io import BytesIO
from docling.datamodel.base_models import DocumentStream
from docling.document_converter import DocumentConverter
data = open("report.pdf", "rb").read() # 例:s3.get_object(...)["Body"].read()
doc = DocumentConverter().convert(DocumentStream(name="report.pdf", stream=BytesIO(data))).document
print(doc.name, len(doc.texts))8 · 最初の数ページだけ#
from docling.document_converter import DocumentConverter
res = DocumentConverter().convert("report.pdf", page_range=(1, 2))
print(len(res.pages), "pages converted")
print(res.document.export_to_markdown()[:200])9 · Word・PowerPoint・Excel を Markdown に#
from docling.document_converter import DocumentConverter
converter = DocumentConverter()
for name in ["memo.docx"]: # .pptx と .xlsx も同じ
md = converter.convert(name).document.export_to_markdown()
print(md)Office ファイルはレイアウトモデルと OCR を通りません。2 段落と表 1 つの Word ファイルは 1 秒もかからず変換されました。
10 · 一度保存すれば、再変換なしで後から書き出せる#
from docling.document_converter import DocumentConverter
from docling_core.types.doc import DoclingDocument
DocumentConverter().convert("report.pdf").document.save_as_json("report.json")
doc = DoclingDocument.load_from_json("report.json") # 一瞬、モデル不要
doc.save_as_html("report.html")
print(doc.export_to_text()[:120])11 · ベクトルストア用にチャンクを JSONL へ#
import json
from docling.chunking import HybridChunker
from docling.document_converter import DocumentConverter
doc = DocumentConverter().convert("report.pdf").document
chunker = HybridChunker(max_tokens=512)
with open("chunks.jsonl", "w") as f:
for i, ch in enumerate(chunker.chunk(doc)):
f.write(json.dumps({
"id": f"report-{i}",
"text": chunker.contextualize(ch),
"headings": ch.meta.headings,
"pages": sorted({p.page_no for it in ch.meta.doc_items for p in it.prov}),
}) + "\n")12 · Web ページを Markdown に#
from docling.document_converter import DocumentConverter
doc = DocumentConverter().convert("https://ja.wikipedia.org/wiki/光学文字認識").document
print(doc.export_to_markdown()[:400])HTML は DOM から解析されるため、見出し・リスト・表を保ったまま高速に変換されます。
よくある質問
公式の Docling サンプルはどこ?
Docling のドキュメントの docling-project.github.io/docling/examples にあります。このページのレシピは独自に書いたもので、より短く、すべて Docling 2.148.0 で実行しています。
古い Docling でも動く?
多くは 2.x から動きますが、一部の API(信頼度レポート、docling.chunking のインポート)は新しいものです。足りない機能があれば、ページ上部に示したバージョンに更新してください。