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内の全テキストを出力するコード。
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追記)。
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が抜けていたので追記しておきました。ご連絡ありがとうございました。
削除