PDFからテキストを抽出するにはPDFを開いてコピペでもできるけれど、一度に大量のPDFを処理するとか、抽出したテキストでさらに何かの処理をしたいときなどは、やはりプログラムでやりたい。というわけで、Python3でPDFからテキストを抽出する方法を調べてみた。
見つけたのがPDFMinerというPDFの構造解析をするPythonライブラリ。これを使ってPDFからテキストを抽出できる。ただしPython2系用なので、Python3にはフォークバージョンのPDFMiner.sixを使う(Python3.4/3.5に対応)。PDFMiner.sixを使ってPDFからテキストを抽出するまでの手順をまとめた。
環境
Raspberry Pi 3 Model B
$ cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core)
$ python3 -V
Python 3.5.2
PDFMiner.sixを使うにはPythonパッケージのpycryptoとsixが必要。
ソースからインストールする方法もあるが、pipを使った方が簡単。
PDFMinerの解説はこちらにある。他にHow do I use pdfminer as a libraryも参考にした。
テキストを抽出するPDFは、青空文庫にある宮沢賢治の「雨ニモマケズ」を青空キンドルでPDFにしたもの。
以下はPDF内の全テキストを出力するコード。
なぜか2つめの「ヰ」だけ「蔭」が「?」になってしまっている。それ以外は問題なし。他のPDFで試したら文字化けはなし。とりあえずこの件は保留。
匿名さんからの情報で、表示段階で文字化けしているよう。結果をファイルに出力してWindowsのnotepadで開くと文字化けしない。
(2017.6.26追記)
PDFにパスワードが設定してあるとPDFが暗号される。PDFMinerでは暗号化PDFからテキスト抽出できない。
どうするかというと、PDF Miner PDFEncryptionErrorでqpdfというツールでPDFを復号化する方法が紹介されている。
まずはqpdfをインストールする。
上記sample1.pyのfp = open('sample.pdf', 'rb')を以下のように変更する。これで暗号化されたPDFからもテキスト抽出ができる。
※「from subprocess import call」などのようにsubprocessモジュールのcallメソッドのインポートもしておく(2018.1.4追記)。
PDFMinerを使うと、ページ単位、あるいはテキストブロックや画像、図表単位で抽出できるので、PDFのデータを抽出して何かやるには便利に使えそうなライブラリである。
見つけたのがPDFMinerというPDFの構造解析をするPythonライブラリ。これを使ってPDFからテキストを抽出できる。ただしPython2系用なので、Python3にはフォークバージョンのPDFMiner.sixを使う(Python3.4/3.5に対応)。PDFMiner.sixを使ってPDFからテキストを抽出するまでの手順をまとめた。
環境
Raspberry Pi 3 Model B
$ cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core)
$ python3 -V
Python 3.5.2
1.必要パッケージインストール
PDFMiner.sixを使うにはPythonパッケージのpycryptoとsixが必要。
2.PDFMinerインストール
ソースからインストールする方法もあるが、pipを使った方が簡単。
3.コードを書く
PDFMinerの解説はこちらにある。他にHow do I use pdfminer as a libraryも参考にした。
テキストを抽出するPDFは、青空文庫にある宮沢賢治の「雨ニモマケズ」を青空キンドルでPDFにしたもの。

以下はPDF内の全テキストを出力するコード。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter from pdfminer.converter import TextConverter from pdfminer.layout import LAParams from pdfminer.pdfpage import PDFPage from io import StringIO rsrcmgr = PDFResourceManager() rettxt = StringIO() laparams = LAParams() # 縦書き文字を横並びで出力する laparams.detect_vertical = True device = TextConverter(rsrcmgr, rettxt, codec = 'utf-8' , laparams = laparams) # 処理するPDFを開く fp = open ( 'sample.pdf' , 'rb' ) interpreter = PDFPageInterpreter(rsrcmgr, device) # maxpages:ページ指定(0は全ページ) for page in PDFPage.get_pages(fp, pagenos = None , maxpages = 0 , password = None ,caching = True , check_extractable = True ): interpreter.process_page(page) print (rettxt.getvalue()) fp.close() device.close() rettxt.close() |
4.結果
なぜか
匿名さんからの情報で、表示段階で文字化けしているよう。結果をファイルに出力してWindowsのnotepadで開くと文字化けしない。
(2017.6.26追記)
5.暗号化PDF対応
PDFにパスワードが設定してあるとPDFが暗号される。PDFMinerでは暗号化PDFからテキスト抽出できない。
どうするかというと、PDF Miner PDFEncryptionErrorでqpdfというツールでPDFを復号化する方法が紹介されている。
まずはqpdfをインストールする。
上記sample1.pyのfp = open('sample.pdf', 'rb')を以下のように変更する。これで暗号化されたPDFからもテキスト抽出ができる。
※「from subprocess import call」などのようにsubprocessモジュールのcallメソッドのインポートもしておく(2018.1.4追記)。
1 2 3 4 | pdf_file = 'sample.pdf' decrypted_file = pdf_file + '.decrypted' call( 'qpdf --password=%s --decrypt %s %s' % ('', pdf_file, decrypted_file), shell = True ) fp = open (decrypted_file, 'rb' ) |
PDFMinerを使うと、ページ単位、あるいはテキストブロックや画像、図表単位で抽出できるので、PDFのデータを抽出して何かやるには便利に使えそうなライブラリである。
[雨ニモマケズ]で表示が?になったのは
返信削除䕃 (utf-8:0xE49583, unicode:0x4543)というCJK統合漢字拡張Aの文字ですが、Shift-JIS や EUC ではこの文字がマッピングされていません。
おそらく、コンバータまではうまくいっていて、それを表示する段階で?になっています。
結果をファイルに出力して、Windowsのnotepadで開くと文字化けしないので、言われるように表示段階で文字化けしているようです。
削除コメントありがとうございました。
暗号化PDFを試したところ、callが未定義とエラーが出ています。対処方法を教えていただければ助かります。
返信削除subprocessをimortしておいてsubprocess.callでうまくいきました。自己解決です。
削除説明にimportが抜けていたので追記しておきました。ご連絡ありがとうございました。
削除