こんにちは、アライアンス事業部のまつおかです。
前回はPDFファイルからテキストを抽出する手順をご紹介しましたが・・・
ここでご紹介した方法は、PDFファイルがテキスト形式の場合に有効なものとなります。
PDFファイルがテキスト形式かどうかはファイルを開いた際にテキストを選択できるかどうかで判断できますが、選択できない場合、つまりテキストが画像として含まれている場合は別の方法を取る必要があります。
ということで今回は、Pythonツールを使って画像形式のPDFファイルからテキストを抽出する方法をご紹介します。
使用環境
- Windows 10 Pro
- Alteryx Designer 2023.1.1.200
使用したPDFファイル
前回同様、青空文庫からいただいてきたテキストのみが入っている以下のようなPDFファイルを使用しました。
処理の概要と事前準備
画像形式のPDFファイルからテキストを抽出するには、PythonからOCR(Optical Character Recognition)を操作します。 OCRを使うと画像内のテキストを認識し編集可能なテキスト形式に変換することができますので、画像形式のPDFファイルからテキストを抽出する場合は一旦1ページずつ画像に変換した上で、OCRを使ってテキスト抽出するという手順になります。
そこで必要になるソフトウェアと、ライブラリを事前にインストールします。
Tesseract OCR のインストール
画像からテキストを抽出するため、光学式文字認識エンジンである「Tesseract OCR」というソフトウェアが必要になります。
インストールの手順はこちらのページがわかりやすいですので参考にしてください。
私が試した2023/10/27時点での最新は「tesseract-ocr-w64-setup-5.3.3.20231005.exe (64 bit)」で、インストーラーを実行した直後、上記のページにはない言語選択画面が表示されました。残念ながら日本語がありませんでしたので、Englishを選択してインストールしました。
それ以降は参照したページと同様に選択し、無事インストールできました。
親切に動作テストの方法まで書かれていますので試してみましたが、うまくテキスト抽出できたのでこの時点でちょっと嬉しくて「おおっ」となりましたw
pdf2image、pyocr のインストール
必要なライブラリとして、pdf2image、pyocr をインストールします。
インストールにはフォルダへの書き込みが必要ですので、権限のない場合は Alteryx Designer を管理者権限で実行(Alteryx Designer のアイコンを右クリックし「管理者権限で実行」をクリック)する必要があります。
from ayx import Package
Package.installPackages("pdf2image")
Package.installPackages("pyocr")
Popplerのインストール
先程インストールしたライブラリ pdf2image
を利用するには、Poppler というPDFファイルを処理するためのライブラリをインストールする必要があります。
インストールの手順はこちらのページがわかりやすいですので参考にしてくだたい。
私が試した2023/10/27時点では「Release-23.10.0-0」が最新でした。
環境変数の「Path」に、ダウンロードして展開した poppler フォルダ内、Library 直下にある bin フォルダのパスを追加すれば完了です。
やってみた
実行環境が整ったところで、作成したワークフローはこちら。
ツールの並びは前回ご紹介したものと全く同じですので、詳細はこちらをご参照ください。
大きく異なるのはPythonツールに記述したコードです。内容はこちら。
from ayx import Alteryx
from PIL import Image
import os
import pyocr
import pyocr.builders
from pdf2image import convert_from_path
import pathlib
import pandas as pd
# ファイル情報取得
PathInf=Alteryx.read("#1")
# パス取得
path = PathInf.iat[0,0]
# Tesseractのパスを通す
path_tesseract = "C:\\Program Files\\Tesseract-OCR"
if path_tesseract not in os.environ["PATH"].split(os.pathsep):
os.environ["PATH"] += os.pathsep + path_tesseract
# OCRエンジンの取得
tools = pyocr.get_available_tools()
tool = tools[0]
data=[]
# ページごとに画像に変換
imgs = convert_from_path(pdf_path)
for page_num, img in enumerate(imgs):
# OCR実行
builder = pyocr.builders.TextBuilder()
text = tool.image_to_string(img, lang="jpn", builder=builder)
# 取得したテキストをリストに追加
data.append([page_num, text])
# アンカー出力用にpandasデータフレーム作成
df = pd.DataFrame(data, columns=["page", "text"])
#アンカー1からデータ出力
Alteryx.write(df,1)
処理の詳細は以下となります。(11、14行目の読込み対象ファイルの情報取得については、前回のブログで説明していますので割愛します)
- 17~19行目で、事前準備でインストールした Tesseract OCR のパスを一時的に環境変数の「Path」に登録しています。
- 22~23行目で
get_available_tools
OCRエンジンを取得しています。今回OCRエンジンとして Tesseract OCR しかインストールしていませんのでtools[0]
で取得できますが、複数のエンジンをインストールしている場合は Tesseract OCR を指定するコードを書く必要があります。 - 28行目で、
convert_from_path
関数を使用し、パラメータで渡されたファイルを1ページごとに画像に変換しています。 - 29~36行目で、1ページずつ画像を取得し、テキストを抽出して出力用のリストに追加しています。
image_to_string
で画像に含まれるテキストを認識し文字列として返すのですが、lngで「jpn」を指定することで、日本語として認識させることができます。
あとはリストからpandasデータフレームを作成し、Pythonツールのアンカー1から出力しています。
出力した結果がこちらです。
ページごとにテキストが取得され、出力できています。
さいごに
以上、画像形式のPDFファイルからテキストを抽出する方法のご紹介でした。
普段PDFを閲覧する際、テキストか画像かを意識することはなかったのですが、今回PDFファイルからのテキスト抽出を試してみて extract_text
では取得できない場合の原因が画像形式であったことを知り、なるほどなーと納得したのでした。
内容的に Alteryx というよりは Python となっている感はありますが・・・参考にしていただければと思います。