派遣で働くエンジニアのスキルアップを応援するサイト

PRODUCED BY RECRUIT

Python×PDF:プログラムでPDFから情報を取得してみよう

Pythonを実際に動かしてみよう!今回のお題は、Python×PDF。ビギナーも取り掛かりやすい、サンプルコードとライブラリをご紹介します。プログラムでPDFファイルからテキストや画像を抽出する方法にぜひトライしてみてください。

【筆者】 watさん
メーカー勤務機械系エンジニア。WATLABブログ運営者。工学計算に関する知識の習得を目指し、Pythonの学習を2019年から始める。仕事以外にも、趣味のプログラミングやPythonコミュニティへの参加を行っている。また、月間数万PVのPythonブログ「WATLAB」を立ち上げ、初心者向けに図を多くしたわかりやすい記事を作成・公開している。著書は『いきなりプログラミング Python』(翔泳社)。
ブログ:https://watlab-blog.com/
 

1.PDFからの情報抽出もPythonが便利

Pythonは強力な外部ライブラリのおかげで、WordやExcel、PowerPoint用のファイルも容易にプログラムから操作できます。PDFも例外ではありません。この記事ではPythonでPDFを操作する方法を紹介します。

PDF(Portable Document Format)は印刷する時のレイアウトを保持したまま閲覧したり編集したりできる、まさに電子の紙と呼ぶべき便利なファイル形式です。WordやExcel、PowerPointで作成したファイルも、配布時にはPDFに変換することがよくあり、事務仕事でPDFを扱う頻度は年々増えてきています。

また昨今ではデジタル化やAIの活用が加速しており、PDFファイルからテキストデータや画像データを自動抽出する技術も需要が高まっています。

PDFから情報を抽出することで、すでに会社が保有している膨大なデジタルデータを有効活用できるでしょう。

さて、必要なコードと、サンプルファイルはご用意しました。手元にPCがある人はサクッと手を動かして、PythonでのPDF操作を試してみてください!

2. Pythonプログラミングの準備

■Pythonプログラミング環境の構築

Pythonプログラミングの環境は「最速でPython環境を構築してプログラミングをはじめよう」を参照してください。リンク先にはPythonのインストール方法、プログラムの記述・実行方法、外部ライブラリのインストール方法をまとめています。

▼Pythonのインストールがまだの方はこちらから!

■必要なライブラリのインストール

今回は次の外部ライブラリをインストールします。

POINT
第0回:最速でPython環境を構築してプログラミングをはじめよう」から始める方は、JupyterLabを立ち上げる前の状態にしておきましょう(仮想環境を使わない場合は5節、仮想環境を使う場合は7節の、いずれもjupyter labコマンドを実行する手前)。

(1)pypdf

pypdfは、PythonでPDFファイルを扱うための外部ライブラリです。PDFの結合、分割、ページの抽出、テキストの抽出といったPDFファイルの操作が可能です。次のコマンドでインストールします。

pip install pypdf

外部ライブラリのインストールが終了したら、以下のコマンドを入力して、JupyterLabを立ち上げましょう。立ち上がったらNotebookと書かれている下のアイコンをクリックします。

jupyter lab

3. サンプルファイル

この記事のコードをすぐに試せるように、2種類の.pdfファイルをサンプルとして用意しました。手元にPDFファイルがない場合は以下のリンクからダウンロードしてお使いください。

▼クリックするとPDFファイルが表示されます。
■sample1
https://www.r-staffing.co.jp/rasisa/wp-content/uploads/2025/02/sample1.pdf

■sample2
https://www.r-staffing.co.jp/rasisa/wp-content/uploads/2025/02/sample2.pdf

サンプルファイルの中身は次の通りです。

◼️sample1.pdf
sample1.pdfは生成AIについてテキストが2ページにわたって書かれたファイルです。
◼️sample2.pdf

sample2.pdfは2枚の画像が添付されている1ページ構成のファイルです。

4. PDFからテキストを抽出する

次のPythonコードは、単一のPDFファイルからテキストを抽出し、その結果をoutput.txtというテキストファイルに保存する、というものです。

解説は後にして、まずはいきなりこのコードをNotebookのセルに書いてみましょう。sample1.pdfはプログラム実行ファイルと同じ場所に置いておきます。

from pypdf import PdfReader

# ファイル名を指定
pdf_file = 'sample1.pdf'
output_file = 'output.txt'

# PDFリーダーオブジェクトを作成
reader = PdfReader(pdf_file)

# テキストファイルを開いて書き込みする
page_num = 1
with open(output_file, 'w', encoding='utf-8') as f:
    for page in reader.pages:
        # テキスト抽出
        text = page.extract_text()
        f.write(f'--- Page {page_num} ---\n')
        f.write(text if text else '')
        f.write('\n\n')
        page_num += 1
POINT
1行目:pypdfのimport
このimport文を書くことでpypdfの機能を使うことができるようになります。
 
POINT
12行目:with文
この行ではファイルを開くopen処理を行っています。
テキストファイルの処理を行う際にwith文を使うと、ファイルオープンからメモリの解放までを自動的に行うことができます。with文を使わないと自分でclose処理まで書く必要があり、忘れてしまうとリソースの解放が適切にできずエラーなどの不具合に繋がる場合があるので積極的に使ってみましょう。
 
POINT
13〜19行目:テキストの抽出結果をファイルに書き込む
for文にreader.pagesを指定することで、PDFファイル内のすべてのページ情報にアクセスできるようになり、1ループで1ページ分の情報を新しく定義した変数pageに格納します。
そしてpage.extract_text()でpageの中からテキストを抽出し、text変数に格納します。
後は.write()を使ってテキストファイルへの書き込みを行っていますが、わかりやすいようにページ番号や改行を前後に追加しました。

このコードを実行するとoutput.txtが新規作成されます。中身は次の内容になっているはずです。

--- Page 1 ---
これはサンプルのPDFファイル1です。 ⽣成AI(Generative AI)とは、⼈⼯知能の⼀分野であり、与えられたデータを基に新たなコンテンツを⾃動的に⽣成する技術です 。例えば、テキスト、画像、⾳声、動画などを⽣成することができます 。この技術は、深層学習(ディープラーニング)に基づいたモデルを使⽤し、⼤量のデータを学習してパターンを把握することで、創造的な成果物を作り出します 。⽣成AIは、コンテンツ作成やデザイン 、翻訳、⾳楽制作、さらには医療や教育の分野にも応⽤されています 。最近では、ChatGPTのような対話型AIや、DALL·Eのような画像⽣成AIが注⽬されています 。⽣成AIは、従来のAIとは異なり、単に⼊⼒に対する出⼒を返すのではなく、過去に学習した情報を基に新しいコンテンツを⽣成する能⼒を持っています。
 
--- Page 2 ---
⽣成AIの今後については、さらなる進化が期待されています 。技術の発展により、⽣成AIはより⾼精度で多様なコンテンツを⽣成できるようになり、創造的な分野における新たな可能性を広げると予測されています 。例えば、映画やゲームの制作、広告のコピーライティング 、さらには個別化された教育コンテンツの提供など、多岐にわたる分野での利⽤が進むでしょう。加えて、⽣成AIは、デザインや芸術の分野で⼈間のクリエイティビティを補完し、これまでにないアイデアやスタイルを提案する役割を果たすことも考えられます 。しかし、倫理的な問題や著作権の問題、AIによる情報の操作といった課題も浮上するため、技術の進展と共に、規制やガイドラインの整備が必要不可⽋となるでしょう。今後は、⽣成AIが社会にどのように影響を与えるかに注⽬が集まります 。

5. PDFから画像を抽出する

続いてPDFから画像を抽出してみましょう。

画像の抽出はテキスト抽出を行う上記コードに追加する形で書いてみます。次のコードを追加してください。pdf_fileには画像が添付されているsample2.pdfを設定しましょう。

from pypdf import PdfReader
import os                   # 追加

# ファイル名を指定
pdf_file = 'sample2.pdf'
output_file = 'output.txt'
img_folder = 'img'          # 追加

# 画像保存フォルダを作成                    # ここから追加
os.makedirs(img_folder, exist_ok=True)  # ここまで追加

# PDFリーダーオブジェクトを作成
reader = PdfReader(pdf_file)

# テキストファイルを開いて書き込みする
page_num = 1
img_count = 1                           # 追加
[省略]
        f.write('\n\n')

        # 画像抽出                                      # ここから追加
        for image_file_object in page.images:
            # 画像名として、連番と元の名前を組み合わせて保存
            img_path = os.path.join(img_folder, f'{img_count}_{image_file_object.name}')
            with open(img_path, 'wb') as img_f:
                img_f.write(image_file_object.data)    # ここまで追加
            img_count += 1

        page_num += 1
 
POINT
2行目, 10行目:フォルダの作成
osをimportすることで.makedirs()によるフォルダ作成が使えるようになります。引数であるexist_okTrueにすることで、すでにフォルダがあるときは何もしなくなります。
 
POINT
27〜32行目:画像抽出
page.imagesでページに含まれる画像リストを作成しています。これをfor文で繰り返し処理し、.write()で画像を保存します。

このコードを実行すると、「img」フォルダが作成され、その中に添付されている画像がすべて抽出されることが確認できるはずです。

6. コードを関数化して複数ファイルに対応させよう

さきほどまでのコードは単一のファイルのみに処理を適用するものでした。しかし、このままでは膨大なPDFを一括で処理することができません。

そこで、これまで作成したコードを関数化し再利用できるようにして、複数のPDFファイルに対して一括で処理が適用できるように改造してみましょう。

次のコードが複数のPDFファイルに対応したものです。プログラム実行フォルダに「PDF」というフォルダを作成し、そこにsample1.pdfとsample2.pdfを入れてください。

from pypdf import PdfReader
from pathlib import Path       # osから変更

def process_pdf(pdf_path):                # これまでのコードを関数化
    """PDFのテキストと画像を抽出する関数"""

    # 出力ファイル名・フォルダ設定
    output_file = pdf_path.with_suffix('.txt')                  # 元の.pdfファイルの名前を使いつつ.txtのパスをつくる処理
    img_folder = pdf_path.with_name(pdf_path.stem + '_img')     # 拡張子を取り除いたファイル名に_imgを追加

    # 画像保存フォルダ作成
    img_folder.mkdir(parents=True, exist_ok=True)               # pathlibの書き方に変更

    # PDFリーダーオブジェクトを作成
    reader = PdfReader(pdf_path)

    page_num = 1
    img_count = 1
    with open(output_file, 'w', encoding='utf-8') as f:
        for page in reader.pages:
            # テキスト抽出
            text = page.extract_text()
            f.write(f'--- Page {page_num} ---\n')
            f.write(text if text else '')
            f.write('\n\n')

            # 画像抽出
            for image_file_object in page.images:
                img_path = img_folder / f'{img_count}_{image_file_object.name}'
                with open(img_path, 'wb') as img_f:
                    img_f.write(image_file_object.data)
                img_count += 1

            page_num += 1
    return                                      # ここまで関数化

# PDFフォルダ               # 追加
pdf_dir = Path('PDF')      # 追加

# PDFフォルダ内の全てのPDFファイルに対して処理           # ここから追加
for pdf_path in pdf_dir.glob('*.pdf'):
    process_pdf(pdf_path)
    print(f"{pdf_path.name} の処理が完了しました。")  # ここまで追加
 
POINT
2行目:pathlibに変更
osからpathlibに変更しました。pathlibはPython標準ライブラリの一つですが、ファイルパスの扱いが簡単にできます。今回のようにフォルダに入っているファイルを一括で処理する時に便利なライブラリです。
 
POINT
4〜35行目:関数化
PDFからテキストと画像を抽出する部分を関数化しました。引数に関数の外で作っているpdf_dirを指定します。pdf_dirは「PDF」というフォルダに入ったすべての.pdfファイルパスのリストです。
output_fileimg_folderは元のPDFファイルのファイル名と関連付けたパスにしています。

このコードを実行すると、PDFフォルダの中に、それぞれのPDFファイルに対応した.txtファイルと画像保存フォルダが一括で作成されました!

7. PDFから抽出したデータの活用方法は無限大

この記事ではPDFファイルからテキストデータや画像データを抽出するPythonコードを紹介しました。

テキスト抽出結果は全文検索機能を実現させる時に使われたり、キーワード抽出や、生成AIを活用した要約作成など幅広く活用ができます。

また、画像データは画像認識AIと組み合わせたり、OCR(光学式文字認識)処理を行うことで、さらに幅広く情報をテキスト化することも可能です。

Pythonは世界中の開発者が日々さまざまな知見を積み上げている活発な言語です。ぜひPythonを活用し、思った機能が簡単に実現できることを体験してみてください。

 

▼これまでの記事もあわせてチェック!

※本記事に記載されている会社名、製品名はそれぞれ各社の商標および登録商標です。
※各記事の内容は掲載時点のものです。

リクルートスタッフィング