この記事では、Pythonを使用して、スキャンされたPDFドキュメントからテキストを抽出する方法について解説します。OCR(光学文字認識)技術を利用することで、画像化されたテキストを文字列データに変換することが可能です。
前提条件
- Python 3.x がインストールされていること
- Tesseract OCR エンジンがインストールされ、パスが通っていること
- [Tesseract OCR GitHub](https://github.com/tesseract-ocr/tesseract)を参照し、OSに合わせてインストールしてください。
- 必要なPythonライブラリがインストールされていること
必要なライブラリ
今回の実装では、主に以下のPythonライブラリを使用します。
| ライブラリ | 説明 |
|---|---|
| PyMuPDF | PDFファイルを操作するためのライブラリです。バージョンによってはfitzとしてインポートする必要があります。 |
| Pillow | Python Imaging Library (PIL) のフォークで、画像処理機能を提供します。 |
| pytesseract | Tesseract OCRエンジンをPythonから利用するためのライブラリです。 |
| pdf2image | PDFを画像に変換するためのライブラリです。Popplerを内部で利用しているため、別途Popplerのインストールとパス設定が必要になる場合があります。(参考ドキュメント) |
これらのライブラリは、以下のコマンドで一括インストールできます。
pip install PyMuPDF Pillow pytesseract pdf2image
実装の流れ
OCR処理は以下の流れで実装します。
- PDFドキュメントを画像に変換
- 各画像に対してOCR処理を実行し、テキストを抽出
- 抽出したテキストを結合し、出力
ステップ1: ドキュメントを画像に変換
まず、pdf2imageライブラリを使って、PDFの各ページを画像に変換します。
from pdf2image import convert_from_path # PDFファイルのパス pdf_path = 'sample.pdf' # PDFを画像(PillowのImageオブジェクト)のリストに変換 images = convert_from_path(pdf_path) print(f"{len(images)} ページが画像に変換されました。")
convert_from_path(pdf_path):pdf_pathで指定されたPDFファイルを読み込み、各ページをPillowのImageオブジェクトのリストとして返します。len(images)でPDFのページ数を確認できます。
ステップ2: 各画像からテキストを抽出 (OCR)
次に、pytesseract ライブラリを使って、各画像からテキストを抽出します。
import pytesseract from PIL import Image # (ステップ1のコードに続けて記述) extracted_text = "" for i, image in enumerate(images): # 日本語のテキストを抽出 (lang='jpn')。必要に応じて言語コードを変更。 text = pytesseract.image_to_string(image, lang='jpn') extracted_text += f'--- Page {i+1} ---\n' extracted_text += text print(f"Page {i+1} のOCR処理が完了しました。") print("すべてのページのOCR処理が完了しました。\n") print(extracted_text)
pytesseract.image_to_string(image, lang='jpn'): image (PillowのImageオブジェクト) に対してOCR処理を行い、結果のテキストを文字列として返します。lang='jpn'で日本語を指定しています。
ステップ3: 抽出したテキストをファイルに保存
抽出したテキストは、ファイルに保存することもできます。
# (ステップ2のコードに続けて記述) output_file = 'output.txt' # 保存するファイル名を指定 with open(output_file, 'w', encoding='utf-8') as f: f.write(extracted_text) print(f"抽出したテキストを {output_file} に保存しました。")
f.write(extracted_text)の処理で抽出した内容extracted_textの中身をファイルに書き込みます。
コードの完成
ここまでの処理を関数にまとめ、再利用しやすい形にして完成です。
完成したextract_text_from_pdf()関数は以下の引数を取り、戻り値として抽出されたテキストを返します。
- pdf_path: PDFファイルのパス
output_txt_path: 出力ファイルパス (省略可能)language: OCRで使用する言語 (デフォルトは日本語)
from pdf2image import convert_from_path import pytesseract from PIL import Image def extract_text_from_pdf(pdf_path, output_txt_path=None, language='jpn'): """ PDFファイルからテキストを抽出し、オプションでファイルに保存する関数。 Args: pdf_path (str): PDFファイルのパス。 output_txt_path (str, optional): テキストを保存するファイルパス。Noneなら保存しない。 language (str, optional): OCRの言語。デフォルトは'jpn' (日本語)。 Returns: str: 抽出されたテキスト。 """ images = convert_from_path(pdf_path) extracted_text = "" for i, image in enumerate(images): text = pytesseract.image_to_string(image, lang=language) extracted_text += f'--- Page {i+1} ---\n' extracted_text += text if output_txt_path: with open(output_txt_path, 'w', encoding='utf-8') as f: f.write(extracted_text) return extracted_text # 関数の使用例 pdf_path = 'sample.pdf' output_file = 'extracted_text.txt' extracted_text = extract_text_from_pdf(pdf_path, output_file) # テキストファイルにも保存 # extracted_text = extract_text_from_pdf(pdf_path) # テキストは保存せずに出力のみ print(extracted_text)
補足事項と注意点
データの前処理による精度向上
OCRの精度は、元の画像品質に大きく左右されます。スキャンされたPDFの場合は、解像度が高いほど良い結果が得られます。必要に応じて、画像処理ライブラリ(Pillowなど)で前処理(ノイズ除去、コントラスト調整など)を行うと精度が向上することがあります。
OCRの言語設定
日本語以外の言語を含むPDFを処理する場合は、pytesseract.image_to_stringのlangパラメータを適切に設定してください。複数の言語が混在している場合は、言語コードを+で結合することも可能です
日本語と英語が混在するドキュメントの例
lang='jpn+eng'
処理速度
OCR処理は単体でも比較的時間がかかる処理です。大量のPDFファイルを処理する場合は、並列処理などを検討してください。
まとめ
PythonとTesseract OCR、関連ライブラリを使用することで、スキャンされたPDFドキュメントから比較的簡単にテキストを抽出できます。この記事で紹介したコードを参考に、OCR処理を実装し、ドキュメントの自動処理を実現してみてください。
退屈なことはPythonにやらせよう 第2版 ノンプログラマーにもできる自動化処理プログラミング [ AI Sweigart ]