PythonでPDFからテキストデータを抽出する方法解説

PythonでPDFからテキストデータを抽出する方法と応用
  • URLをコピーしました!

当ブログのコンテンツ・情報について、できる限り正確な情報を提供するように努めておりますが、正確性や安全性を保証するものではありません。
当サイトに掲載された内容によって生じた損害等の一切の責任を負いかねますので、予めご了承ください。

この記事では、Pythonライブラリ「PyMuPDF」を使って、PDFからテキストデータを効率的に抽出する方法をご紹介します。この記事を読むことで、Pythonを用いてPDFファイルから必要なテキストデータを取り出し、加工するスキルを身につけることができます。

目次

この記事で使用するPythonライブラリ

この記事では以下のPythonライブラリを使用します。

ライブラリ用途ライセンス
PyMuPDFPDFやXPSなどの操作AGPL、商用ライセンス
re正規表現による文字列の操作Python標準モジュール
unicodedataUnicode文字の情報取得と操作Python標準モジュール
osファイルやフォルダの操作Python標準モジュール

PyMuPDFとは

PyMuPDF(公式サイト)は、PDFやXPSなどのファイルからデータを抽出するためのPythonライブラリです。このライブラリは、高速で軽量なPDF処理を実現することができます。

PyMuPDFはオープンソースのAGPLと商用ライセンスのデュアルライセンスで提供されています。

PDFからテキストデータを抽出する方法

ここでは、例として日本の公開特許公報を使ってテキストデータを抽出する方法をご紹介します。特許公報はJ-PlatPatGoogle Patentsから無料で入手できます。

今回は例として特開2024-096983のPDFファイルを引用させていただきます。

PyMuPDFのインストール

PyMuPDFを使用するには、まずPythonの環境にインストールする必要があります。PowerShellで以下のコマンドを実行してください。

pip install pymupdf

生テキストを抽出

まず、PDFファイルから生テキストを抽出する基本的な方法について説明します。PyMuPDFを使ってPDFを開き、各ページからテキストを抽出します。以下は、Pythonコードの基本的な例です。

import fitz  # PyMuPDFをインポート

def pdf_to_txt(pdf_path, txt_path):
    # PDFファイルを開く
    pdf_document = fitz.open(pdf_path)
    # .txtファイルを作成
    with open(txt_path, 'w', encoding='utf-8') as txt_file:
        # PDFの各ページを処理
        for page_num in range(len(pdf_document)):
            page = pdf_document.load_page(page_num)
            text = page.get_text()
            txt_file.write(text)

# PDFファイルのパス
pdf_path = r'C:\py\PyMuPDF\example.pdf'
# 出力する.txtファイルのパス
txt_path = r'C:\py\PyMuPDF\output.txt'

# PDFからテキストを抽出して.txtに保存
pdf_to_txt(pdf_path, txt_path)

このコードでは、以下の処理をしています。

  1. 処理するPDFファイルをパス(pdf_path = r'C:\py\PyMuPDF\example.pdf')で指定
  2. 出力するTXTファイルをパス(txt_path = r'C:\py\PyMuPDF\output.txt')で指定
  3. example.pdfからfor文で各ページのテキストを抽出
  4. output.txtに出力して保存

出力結果は下記のとおりです。基本的なテキスト抽出はできていますが、余分な改行や空白、ヘッダーやフッター情報が含まれており、このままでは扱いづらいテキストになっています。

JP 2024-96983 A 2024.7.17
(57)【要約】   (修正有)
【課題】ニューラルネットワーク等の機械学習モデルを
自動生成する方法を提供する。
【解決手段】ハードウェア処理ユニット及び記憶資源を
含むシステムにおいて、記憶資源は、コンピュータ可読
命令を記憶する。ハードウェア処理ユニットは、コンピ
ュータ可読命令により親モデルを修正して子モデルを得
ることを含む反復的モデル成長プロセスを実行する。反
復的モデル成長プロセスは、候補層の初期化プロセス内
で学習される重みに少なくとも基づいて子モデルに含め
る候補層を選択することも含む。システムはまた、子モ
デルから選択される最終モデルを出力する。
【選択図】図1
(2)
JP 2024-96983 A 2024.7.17
【特許請求の範囲】
--中略--
【請求項7】
 それぞれの候補層を生成することが、
 前記それぞれの候補層の出力を受信するために前記特定の親モデルからターゲット層を
10
20
30
40
50
(3)
JP 2024-96983 A 2024.7.17
選択すること、
--中略--
【背景技術】
【0001】
背景
 [0001] 従来から、機械学習モデルは、モデルの構造を定め、モデルを訓練するために
自動化された技法を使用する専門家によって手動で構築されてきた。機械学習モデルがよ
り複雑に成長するにつれ、機械学習モデルを生成するプロセスを自動化するための様々な
試みが行われてきた。しかし、それらの努力に対する成果は限られたものであった。
【発明の概要】
【課題を解決するための手段】
【0002】
概要
 [0002] この概要は、
--以下略--

余分な空白と改行の処理

まずは、改行と空白を処理します。以下のコード例では、改行、全角スペース及び半角スペースをを長さ0の文字列("")に置換しています。

import fitz  # PyMuPDFをインポート

def pdf_to_txt(pdf_path, txt_path):
    # PDFファイルを開く
    pdf_document = fitz.open(pdf_path)
    # .txtファイルを作成
    with open(txt_path, 'w', encoding='utf-8') as txt_file:
        # PDFの各ページを処理
        for page_num in range(len(pdf_document)):
            page = pdf_document.load_page(page_num)
            text = page.get_text()

            # 改行を置換する処理
            text = text.replace('\n', '')

            # 全角スペース及び半角スペースを削除する処理
            text = text.replace(' ', '').replace(' ', '')

            txt_file.write(text)

# PDFファイルのパス
pdf_path = r'C:\py\PyMuPDF\example.pdf'
# 出力する.txtファイルのパス
txt_path = r'C:\py\PyMuPDF\output.txt'

# PDFからテキストを抽出して.txtに保存
pdf_to_txt(pdf_path, txt_path)

出力結果は下記のとおりです。改行やスペースは除去できましたが、ヘッダーやフッター等の余分な文字列(青線)が残ってしまっています。

JP2024-96983A2024.7.17(57)【要約】(修正有)【課題】ニューラルネットワーク等の機械学習モデルを自動生成する方法を提供する。【解決手段】ハードウェア処理ユニット及び記憶資源を含むシステムにおいて、記憶資源は、コンピュータ可読命令を記憶する。ハードウェア処理ユニットは、コンピュータ可読命令により親モデルを修正して子モデルを得ることを含む反復的モデル成長プロセスを実行する。反復的モデル成長プロセスは、候補層の初期化プロセス内で学習される重みに少なくとも基づいて子モデルに含める候補層を選択することも含む。システムはまた、子モデルから選択される最終モデルを出力する。【選択図】図1(2)JP2024-96983A2024.7.17【特許請求の範囲】
--中略--
請求項7】それぞれの候補層を生成することが、前記それぞれの候補層の出力を受信するために前記特定の親モデルからターゲット層を1020304050(3)JP2024-96983A2024.7.17選択すること、
--中略--
【背景技術】【0001】背景[0001]従来から、機械学習モデルは、モデルの構造を定め、モデルを訓練するために自動化された技法を使用する専門家によって手動で構築されてきた。機械学習モデルがより複雑に成長するにつれ、機械学習モデルを生成するプロセスを自動化するための様々な試みが行われてきた。しかし、それらの努力に対する成果は限られたものであった。【発明の概要】【課題を解決するための手段】【0002】概要[0002]この概要は、
--以下略--

正規表現を利用した余分な文字列の除去

ヘッダー等の余分な文字列が全く同じ文字列であれば、改行や空白のように単に置換すれば問題ありません。しかし、ページ数のように文字列が変化する場合は正規表現を利用して処理します。正規表現を利用するにはPythonの"re"モジュールを使用します。

公開特許公報PDFの余分な文字列は、以下の規則に従っています。

"2桁~10桁の数値"+"(数値)"+"JP"+"西暦"+"-"+6桁以下の数値"+"A"+"西暦"+"."+"月"+"."+"日"

ここで、注意するのは"2桁~10桁の数値"とそれ以降はページが跨っていることです。このような場合、まずは全ページのテキストを抽出後、テキストを結合してから正規表現で処理を行う必要があります。

import fitz  # PyMuPDFをインポート
import re  # 正規表現モジュールをインポート

def pdf_to_txt(pdf_path, txt_path):
    # PDFファイルを開く
    pdf_document = fitz.open(pdf_path)
    # 全ページのテキストを格納するリスト
    all_text = []

    # PDFの各ページを処理
    for page_num in range(len(pdf_document)):
        page = pdf_document.load_page(page_num)
        text = page.get_text()

        # 改行を置換する処理
        text = text.replace('\n', '')

        # 全角スペース及び半角スペースを削除する処理
        text = text.replace(' ', '').replace(' ', '')

        # 各ページのテキストをリストに追加
        all_text.append(text)

    # 全ページのテキストを結合
    combined_text = ''.join(all_text)

    # ヘッダーやフッターなどの情報を正規表現で除去する処理
    pattern = r'(\d{2,10})?(\(\d\))?JP\d{4}-\d{1,6}A\d{4}\.\d{1,2}\.\d{1,2}'
    combined_text = re.sub(pattern, '', combined_text)

    # .txtファイルを作成して書き込む
    with open(txt_path, 'w', encoding='utf-8') as txt_file:
        txt_file.write(combined_text)

# PDFファイルのパス
pdf_path = r'C:\py\PyMuPDF\example.pdf'
# 出力する.txtファイルのパス
txt_path = r'C:\py\PyMuPDF\output.txt'

# PDFからテキストを抽出して.txtに保存
pdf_to_txt(pdf_path, txt_path)

出力結果は下記のとおりです。

(57)【要約】(修正有)【課題】ニューラルネットワーク等の機械学習モデルを自動生成する方法を提供する。【解決手段】ハードウェア処理ユニット及び記憶資源を含むシステムにおいて、記憶資源は、コンピュータ可読命令を記憶する。ハードウェア処理ユニットは、コンピュータ可読命令により親モデルを修正して子モデルを得ることを含む反復的モデル成長プロセスを実行する。反復的モデル成長プロセスは、候補層の初期化プロセス内で学習される重みに少なくとも基づいて子モデルに含める候補層を選択することも含む。システムはまた、子モデルから選択される最終モデルを出力する。【選択図】図1【特許請求の範囲】
--中略--
【請求項7】それぞれの候補層を生成することが、前記それぞれの候補層の出力を受信するために前記特定の親モデルからターゲット層を選択すること、前記それぞれの候補層に入力を与えるために前記特定の親モデルから1つ又は複数の入力層を選択すること、
--中略--
【背景技術】【0001】背景[0001]従来から、機械学習モデルは、モデルの構造を定め、モデルを訓練するために自動化された技法を使用する専門家によって手動で構築されてきた。機械学習モデルがより複雑に成長するにつれ、機械学習モデルを生成するプロセスを自動化するための様々な試みが行われてきた。しかし、それらの努力に対する成果は限られたものであった。【発明の概要】【課題を解決するための手段】【0002】概要[0002]この概要は、
--以下略--

全角英数字から半角英数字への処理

日本の特許公報では全角の英数字が使用されています。ケースバイケースですが、半角にすることでテキストの統一性が保たれ後の処理が容易になることがあります。全角英数字を半角英数字にするにはPythonの"unicodedata"モジュールを使用します。

以下のコードでは、unicodedata.normalize('NFKC', char)を使用して、全角英数字を半角に変換しています。

import fitz  # PyMuPDFをインポート
import re  # 正規表現モジュールをインポート
import unicodedata  # Unicodeデータベースをインポート

def pdf_to_txt(pdf_path, txt_path):
    # PDFファイルを開く
    pdf_document = fitz.open(pdf_path)
    # 全ページのテキストを格納するリスト
    all_text = []

    # PDFの各ページを処理
    for page_num in range(len(pdf_document)):
        page = pdf_document.load_page(page_num)
        text = page.get_text()

        # 改行を置換する処理
        text = text.replace('\n', '')

        # 全角スペース及び半角スペースを削除する処理
        text = text.replace(' ', '').replace(' ', '')

        # 各ページのテキストをリストに追加
        all_text.append(text)

    # 全ページのテキストを結合
    combined_text = ''.join(all_text)

    # ヘッダーやフッターなどの情報を除去する処理
    pattern = r'(\d{0,10})?\(?(\d{0,10})?\)?JP\d{4}-\d{1,6}A\d{4}\.\d{1,2}\.\d{1,2}'
    combined_text = re.sub(pattern, '', combined_text)

    # 全角英数字を半角に変換する処理
    combined_text = unicodedata.normalize('NFKC', combined_text)

    # .txtファイルを作成して書き込む
    with open(txt_path, 'w', encoding='utf-8') as txt_file:
        txt_file.write(combined_text)

# PDFファイルのパス
pdf_path = r'C:\py\PyMuPDF\example.pdf'
# 出力する.txtファイルのパス
txt_path = r'C:\py\PyMuPDF\output.txt'

# PDFからテキストを抽出して.txtに保存
pdf_to_txt(pdf_path, txt_path)

出力結果は以下のとおりです。

(57)【要約】(修正有)【課題】ニューラルネットワーク等の機械学習モデルを自動生成する方法を提供する。【解決手段】ハードウェア処理ユニット及び記憶資源を含むシステムにおいて、記憶資源は、コンピュータ可読命令を記憶する。ハードウェア処理ユニットは、コンピュータ可読命令により親モデルを修正して子モデルを得ることを含む反復的モデル成長プロセスを実行する。反復的モデル成長プロセスは、候補層の初期化プロセス内で学習される重みに少なくとも基づいて子モデルに含める候補層を選択することも含む。システムはまた、子モデルから選択される最終モデルを出力する。【選択図】図【特許請求の範囲】
--中略--
【請求項7】それぞれの候補層を生成することが、前記それぞれの候補層の出力を受信するために前記特定の親モデルからターゲット層を選択すること、
--中略--
【背景技術】【0001】背景[0001]従来から、機械学習モデルは、モデルの構造を定め、モデルを訓練するために自動化された技法を使用する専門家によって手動で構築されてきた。機械学習モデルがより複雑に成長するにつれ、機械学習モデルを生成するプロセスを自動化するための様々な試みが行われてきた。しかし、それらの努力に対する成果は限られたものであった。【発明の概要】【課題を解決するための手段】【0002】概要[0002]この概要は、
--以下略--

複数のPDFファイルの連続処理

多数のPDFファイルを一度に処理する場合、それぞれのファイルを手動で処理するのは効率的ではありません。

for 文を使えば、指定したフォルダ内のすべてのPDFファイルを自動で処理し、対応するテキストファイルに変換することができます。ファイルやフォルダの操作をするにはPythonの"os"モジュールを使用します。

このコードでは、以下のように指定されたフォルダ内のすべてのPDFファイルを処理し、その得られたテキストファイルを「OUTPUT」フォルダに保存するようにしています。

  1. pdf_to_txt関数: 指定されたPDFファイルからテキストを抽出し、指定されたパスに.txtファイルとして保存
  2. process_pdfs_in_folder関数: 指定されたフォルダ内のすべてのPDFファイルを順次処理し、抽出したテキストを「OUTPUT」フォルダに保存
  3. folder_path変数: PDFファイルが含まれるフォルダのパスを指定し、このパス内のPDFファイルを処理
import fitz  # PyMuPDFをインポート
import re  # 正規表現モジュールをインポート
import unicodedata  # Unicodeデータベースをインポート
import os  # OSモジュールをインポート

def pdf_to_txt(pdf_path, txt_path):
    # PDFファイルを開く
    pdf_document = fitz.open(pdf_path)
    all_text = []

    # PDFの各ページを処理
    for page_num in range(len(pdf_document)):
        page = pdf_document.load_page(page_num)
        text = page.get_text()

        # 改行を置換する
        text = text.replace('\n', '')

        # 全角スペース及び半角スペースを削除
        text = text.replace(' ', '').replace(' ', '')

        # 各ページのテキストをリストに追加
        all_text.append(text)

    # 全ページのテキストを結合
    combined_text = ''.join(all_text)

    # ヘッダーやフッターなどの情報を除去
    pattern = r'(\d{0,10})?\(?(\d{0,10})?\)?JP\d{4}-\d{1,6}A\d{4}\.\d{1,2}\.\d{1,2}'
    combined_text = re.sub(pattern, '', combined_text)

    # 全角英数字を半角に変換
    combined_text = unicodedata.normalize('NFKC', combined_text)

    # .txtファイルを作成して書き込む
    with open(txt_path, 'w', encoding='utf-8') as txt_file:
        txt_file.write(combined_text)

def process_pdfs_in_folder(folder_path):
    # OUTPUTフォルダのパスを作成
    output_folder = os.path.join(folder_path, "OUTPUT")

    # OUTPUTフォルダが存在しない場合は作成
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)

    # フォルダ内の全ファイルを取得
    for file_name in os.listdir(folder_path):
        # PDFファイルのみを対象に処理
        if file_name.endswith('.pdf'):
            pdf_path = os.path.join(folder_path, file_name)
            txt_path = os.path.join(output_folder, f"{os.path.splitext(file_name)[0]}.txt")
            
            # PDFからテキストを抽出して.txtに保存
            pdf_to_txt(pdf_path, txt_path)

# 処理するフォルダのパス
folder_path = r'C:\py\PyMuPDF'

# フォルダ内のPDFファイルを処理
process_pdfs_in_folder(folder_path)

まとめ

PyMuPDFライブラリを使用することで、高速かつ効率的にPDFから必要な情報を取り出すことができます。

様々な形式のPDFにも対応できるよう、改行の処理やヘッダー、フッターの除去、全角から半角への変換などの工夫が必要です。これらの手法を活用して、PDFのデータ抽出作業を自動化し、業務の効率化を図りましょう。

よかったらシェアしてね!
  • URLをコピーしました!
目次