見出し画像

154 #PyMuPDF PDFファイルからテキストのレイアウトを保ちながら文字抽出する方法 ページNOと区切り線を出力編

はじめに

こんにちは!TechCommitメンバーの友季子です♬ 今回は、PDFファイルからテキストをレイアウトを保ちながら抽出する&ページNOと区切り線を出力する方法についてまとめてみました。

具体的にはPythonのPyMuPDFというライブラリを使って、PDF化ファイル=>メモ帳へテキストファイルにて抽出する方法です。
PDFのデータ整理や、テキスト抽出が必要な方にお役に立てればと思い執筆しました。


input

ExcelをPDF形式にて保存

output

メモ帳※Windows ページ数と区切り線が入ったよ!


1.必要な準備

今回のコードを実行するには、Pythonのライブラリ「PyMuPDF」(fitz として使用)を使います。まずは、このライブラリをインストールしましょう。

pip install pymupdf

次に、Pythonで処理するPDFファイルのパスと、保存先のテキストファイルのパスを用意します。ここでは、次のように準備します。

  • PDFファイルのパス: hogehoge/input.pdf

  • 保存先のテキストファイルパス: hogehoge/output.txt

2.コードの解説

以下が、PDFの内容をテキストに変換し、ページごとに分けてテキストファイルに保存するためのコードです。PDFのレイアウトを保ちつつテキストを抽出し、さらにデバッグ用のメッセージを追加しています。

サンプルコード

import fitz  # PyMuPDFをインポート
import os

# PDFファイルのパス
pdf_path = 'C:/hogehoge112kakidasirist.pdf'
# 保存先のテキストファイルパス
output_txt_path = r'C:\hogehogehogehoge.txt'

# 出力先のフォルダが存在しない場合、作成する
output_folder = os.path.dirname(output_txt_path)
if not os.path.exists(output_folder):
    os.makedirs(output_folder)
    print(f"フォルダ '{output_folder}' を作成しました。")


def extract_text_with_layout(pdf_path, txt_output_path):
    print(f"PDFファイル '{pdf_path}' を開いています...")
    # PDFファイルを開く
    with fitz.open(pdf_path) as pdf:
        print(f"{pdf.page_count} ページのPDFファイルを読み込みました。")

        # テキストファイルを開く(書き込みモード)
        with open(txt_output_path, 'w', encoding='utf-8') as txt_file:
            print(f"出力先テキストファイル '{txt_output_path}' を作成しました。")

            # 各ページからテキストを抽出
            for page_num in range(pdf.page_count):
                print(f"ページ {page_num + 1} を処理しています...")
                page = pdf[page_num]

                # レイアウトを保ちながらテキストを取得
                text = page.get_text("text")  # "text" モードで抽出
                if text:
                    print(f"ページ {page_num + 1} のテキストを取得しました。")
                    # デバッグ用: テキストの最初の100文字だけを表示
                    print(f"ページ {page_num + 1} のテキスト内容の一部:\n{text[:100]}...\n")
                else:
                    print(f"ページ {page_num + 1} にテキストが見つかりませんでした。")

                # ページ番号をメモの見出しとして追加
                txt_file.write(f"--- Page {page_num + 1} ---\n")
                txt_file.write(text)
                txt_file.write("\n" + "=" * 40 + "\n\n")  # ページの区切り

            print("すべてのページの処理が完了しました。")
    print("PDFからのテキスト抽出が完了しました。")


# 関数を実行
extract_text_with_layout(pdf_path, output_txt_path)

コメント解説

import fitz  # PyMuPDFをインポート
import os

# PDFファイルのパス
pdf_path = 'C:/hogehoge1112kakidasirist.pdf'
# 保存先のテキストファイルパス
output_txt_path = r'C:\yhedgehogkakidasi.txt'

# 出力先のフォルダが存在しない場合、作成する
output_folder = os.path.dirname(output_txt_path)
if not os.path.exists(output_folder):  # 指定したフォルダが存在しないかを確認します
    os.makedirs(output_folder)  # フォルダがなければ新しく作成します
    print(f"フォルダ '{output_folder}' を作成しました。")  # フォルダ作成のメッセージを表示

# PDFからテキストを抽出する関数を定義
def extract_text_with_layout(pdf_path, txt_output_path):
    print(f"PDFファイル '{pdf_path}' を開いています...")  # 処理開始メッセージ

    # PDFファイルを開く
    with fitz.open(pdf_path) as pdf:  # PDFファイルを開き、`pdf`として使用
        print(f"{pdf.page_count} ページのPDFファイルを読み込みました。")  # ページ数を表示

        # テキストファイルを開く(書き込みモード)
        with open(txt_output_path, 'w', encoding='utf-8') as txt_file:  # 書き込み用テキストファイルを作成
            print(f"出力先テキストファイル '{txt_output_path}' を作成しました。")  # テキストファイル作成のメッセージを表示

            # 各ページからテキストを抽出
            for page_num in range(pdf.page_count):  # 各ページを順に処理します
                print(f"ページ {page_num + 1} を処理しています...")  # 現在のページ番号を表示
                page = pdf[page_num]  # 現在のページを指定

                # レイアウトを保ちながらテキストを取得
                text = page.get_text("text")  # PDFのレイアウトに従ってテキストを取得
                if text:  # テキストが存在する場合のみ
                    print(f"ページ {page_num + 1} のテキストを取得しました。")  # テキスト取得のメッセージを表示
                    # デバッグ用: テキストの最初の100文字だけを表示
                    print(f"ページ {page_num + 1} のテキスト内容の一部:\n{text[:100]}...\n")  # テキストの一部を表示
                else:
                    print(f"ページ {page_num + 1} にテキストが見つかりませんでした。")  # テキストが見つからない場合のメッセージ

                # ページ番号をメモの見出しとして追加
                txt_file.write(f"--- Page {page_num + 1} ---\n")  # ページ番号の見出しを追加
                txt_file.write(text)  # ページのテキストをテキストファイルに書き込み
                txt_file.write("\n" + "=" * 40 + "\n\n")  # ページの区切り線を追加

            print("すべてのページの処理が完了しました。")  # すべてのページの処理完了メッセージ
    print("PDFからのテキスト抽出が完了しました。")  # 処理の終了メッセージ

# 関数を実行
extract_text_with_layout(pdf_path, output_txt_path)  # 実際に関数を呼び出し、テキスト抽出を開始
コードのポイント

大事なポイント

  • page.get_text("text") モードを使うことで、PDFの段組や改行を保ちながらテキストを抽出できます。

  • 各ページの最初にページ番号と区切り線を追加して、見やすく仕上げています。

  • print 文でデバッグ情報を出力し、各ページが正しく処理されているか確認できます。

エンジニア向け補足解説

  • fitzはPyMuPDFライブラリの別名で、PDFの読み込みに使用します。ここではPDFからテキストを抽出するために使います。

  • ファイルのパスは、PDFの読み取り元(pdf_path)と、書き込むテキストファイルの保存先(output_txt_path)を指定します。

  • os.path.dirname()とos.makedirs()を使って、保存先のフォルダが存在しない場合に自動で作成します。

  • with文でPDFファイルやテキストファイルを開き、読み込みや書き込みが終わったら自動的に閉じます。

実行後、hogehoge/output.txt にPDFの内容がページごとに保存されます。さらに、各ページの内容を確認するためのデバッグメッセージがターミナルに表示されます。これにより、各ページのテキストが正しく抽出できているかもすぐに確認できます。


終わりに

いかがでしたか?この方法を使えば、PDFからレイアウトを保ったテキスト抽出が簡単にできます。PDFデータの整理や分析にお役に立てれば幸いです!

#page.get_text("text") #PyMuPDF


いいなと思ったら応援しよう!