この記事を読むのに必要な時間は 約8分 です。
前回記事はこちらです👇
https://clshinji.com/python-1pdf情報のフィルタリングを目指して/117/
PDFからテキストを抽出したい
前回記事にて「スシローのアレルギー情報をチェックできるチャットボット」を作成することを目指して、Pythonでの開発にチャレンジすることを表明させていただきました。
スシローさんのアレルギー情報は「PDF形式」で公開されていますので、今回は
PDFからテキストを抽出する
ことについて試してみました。
PDFの情報を読み取れるPythonライブラリを試す!
PDFに書かれている表のデータを読み取るためには、PDFのテキストを抽出する必要があります。
調べてみたところ、文字認識(OCR)だと「PDFMiner」というのが日本語への対応も良いようなので少し試してみました。
ところが、アレルギー情報の上の方にある説明書き等を読み取ってしまい、その後のデータ処理がし辛いデータしか取り出せませんでした…(ぐぬぬ)
そこで私は気づきました
結局欲しい情報は、表(テーブル)データ!!
改めてググってみたら、あるじゃないですか。PDFから表データを読み取れるtabula-py!
こちらのライブラリは、PDFから表のデータを読み取り、それをPandasデータフレーム形式で出力してくれる優れものです。
今回やりたいことにベストマッチですね。
Tabula-pyによるPDF読み取りの実装&データ型のチェック
今回参考にさせていただいたサイトはこちらです👇
【Qiita】PythonでPDFファイルのテーブルデータを読み取る
<以下、更に詳しく見たい方向け>
開発元のGitHubのページ 👉https://github.com/chezou/tabula-py
tabula-py公式ドキュメント👉https://tabula-py.readthedocs.io/en/latest/tabula.html
ほとんど問題ないかと思いますが、Javaを使用しているライブラリとのことで、事前にJavaのインストールが必要とのことです。
ということで、tabula-pyのインストールを進めていきます。
インストールは簡単で、いつもどおり以下のpipコマンドでインストールしていきます。
$ pip install tabula-py
インストールは時間がかからず、1分もかからず完了です。
早速、スシローのアレルギー情報のPDFファイルで試していきます!
※2023年6月12日時点でのアレルギー情報のPDFファイルを読み込んでいます
import tabula
import pandas as pd
df = tabula.read_pdf('allergy.pdf', pages='all')
使い方はシンプルで、read_pdfを呼び出して「pdfファイルのパス」を指定して読み込みます。
オプションの「pages」で読み込みたいページを指定できます。
デフォルトだと1になりますので、1ページだけ読み込まれます。
他には、下表のようにpagesに指定する引数によって、読み込まれるPDFのページを指定できるようです。
pagesで指定する引数 | 読み込まれるページ |
‘1-2,4’ | 1〜2ページ&4ページ目 |
‘all’ | 全てのページ |
‘[1,4]’ | 1ページ目と4ページ目 |
読み込まれたデータフレームを確認すると、以下のとおり「長さ10のリスト型」となっておりました。
df type: <class 'list'>
df len : 10
ということで、1ページ目のデータがちゃんと読み込まれているか、dfの1要素目を取り出してみると、下表のようになってしまっています。
※df[0].head(10)の中身です👇
Unnamed: 0 | Unnamed: 1 | 卵 | 乳 | 小 | え | か | そ | 落 | く | ア | あ | い | い.1 | オ | カ | キ | 牛 | ご | さ | さ.1 | 大 | 鶏 | バ | 豚 | ま | も | や | り | ゼ | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | NaN | NaN | NaN | 成 | 麦 | び | に | ば | 花 | る | ー | わ | か | く | レ | シ | ウ | 肉 | ま | け | ば | 豆 | 肉 | ナ | 肉 | つ | も | ま | ん | ラ |
1 | NaN | NaN | NaN | 分 | NaN | NaN | NaN | NaN | 生 | み | モ | び | NaN | ら | ン | ュ | イ | NaN | NaN | NaN | NaN | NaN | NaN | ナ | NaN | た | NaN | い | ご | チ |
2 | 区分 | メニュー名称 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ン | NaN | NaN | NaN | ジ | ー | フ | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | け | NaN | も | NaN | ン |
3 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ナ | ル | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
4 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ド | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
5 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ッ | ー | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
6 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ツ | ツ | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
7 | 寿司 | 青森産生サーモン | ○ | ○ | ○ | ○ | ○ | NaN | NaN | NaN | NaN | NaN | ○ | ○ | NaN | NaN | NaN | ○ | ○ | ● | ○ | ○ | NaN | NaN | ○ | NaN | NaN | NaN | ○ | NaN |
8 | 寿司 | 赤えび | NaN | NaN | ○ | ● | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ○ | NaN | NaN | NaN | ○ | NaN | NaN | ○ | NaN | NaN | NaN | ○ | NaN |
9 | 寿司 | 炙り3貫盛り | ○ | ○ | ○ | ● | ○ | NaN | NaN | NaN | NaN | NaN | ○ | ○ | NaN | NaN | NaN | ○ | ○ | ● | ○ | ○ | NaN | NaN | ○ | NaN | NaN | NaN | ○ | NaN |
本来は、列名に「卵」「乳成分」「小麦」…と書かれていますが、縦書きだったので誤認してしまっていますね。
とはいえ、PDFの全てのページをデータフレーム形式で読み込むことには成功しました…!
ここからはPandasを使用してデータフレームの整形をしていきたいと思います。
少し長くなってきましたので、続きは次の記事でまとめたいと思います。
次の記事はこちらからどうぞ👇
https://clshinji.com/【python】pdfのテキストを抽出する<第3回>/140/
コメント