PythonでPDFを読み込むメモ(decrypt有)
はじめに
ネット上にはPDF化されたファイルが多いが、そのデータを読み込むには一癖必要である。帳票や授業で撮ったノートなんかを画像からPDFに変換した時だったり、オフィシャルなPDFファイルだったり。
そんなPDFファイルからPythonで文字データを抽出するにはどうすれば良いか?というメモ
環境
- macOS Catalina 10.15.4
- Python==3.7.4 on Anaconda==1.7.2 (conda==4.8.3)
- pip==19.2.3
- PyPDF2==1.26.0
- pikepdf==1.13.0
参考URL
なお、参考にしたURLはこちらに先に示しておく。
対象としているPDFファイル
本記事で対象としているPDFファイルは、
- 英語/数字で記述
- ロックの有無(decrypted/encrypted)は問わない
である。日本語のPDFに関しては、本記事では試していないので、読者らで試してみて欲しい(なんなら所感をコメントに残してほしいです)
PythonにおけるPDF reader
こちらの記事に纏まっているので、詳細(詳細というレベルで記述されている記事ではないが)を知りたければそちらを。PythonでPDFを読み込むために使用できるpackageは、以下のようなものがある。
Package | 対象 | install command |
---|---|---|
PyPDF2 | 英語 | pip install PyPDF2 |
pdfminer.six | 日本語 | pip install pdfminer.six |
Apache Tika | 日本語 | pip install tika |
Tesseract OCR | 画像データのPDFや帳票PDF | pip install pyocr |
今回私が使用するのは、英語を対象としているためPyPDF2
である。なお、こちらに関しては、すでにPyPDF3
が開発されている(PyPDF2
を開発していた人らが開発を中断してしまったが、こちらのソフトが如何せん有用だったため有志で開発が進められている(しかしそこまで活発ではないし、現状はPyPDF2
で十分だろう))。
なお、フォントに依存して読み込めないものも存在することには留意しよう。
復号化(Decrypt)の必要性
読み込ませたいPDFファイルが、例えばネット上から拾ってきたものであったり、自分配布用に作成したものであったりすると、大抵はロックがかけられているだろう(第三者に編集させないようにするため)。その状態のものをPyPDF2
で読み込ませようとすると、以下のようなエラーを吐く。
import PyPDF2 with open("hogehoge.pdf", mode='rb') as f: reader = PyPDF2.PdfFileReader(f) print(f"Number of pages: {reader.getNumPages()}") >>> PdfReadError: File has not been decrypted
これは、「暗号化されているため復号化してくださいね」というエラーである。
PyPDF2上における復号化
もし、そのPDFにかけられているロックのパスワードが既知("fugafuga"
)である場合、PyPDF2
上でアンロックする(decrypt)ことが可能である。
import PyPDF2 with open("hogehoge.pdf", mode='rb') as f: reader = PyPDF2.PdfFileReader(f) if reader.isEncrypted: reader.decrypt("fugafuga") print(f"Number of pages: {reader.getNumPages()}")
if reader.isEncrypted:
と、ロックされているかどうか(復号化の必要があるか)を確認できる。これでもロックを解除することができない場合には、
NotImplementedError: only algorithm code 1 and 2 are supported
というエラーを吐くことがある。その際には、qpdf
と呼ばれるツールを使用することを推奨している記事が多数見受けられる(NotImplimentedError
が、そもそもその復号化処理をPyPDF2
で担うことができないということに起因するので、復号化処理だけqpdf
に担ってもらおうという考え方)が、これもまたパスワードが既知であるPDFファイルにしか対応できない。現実問題、そんなにパスワードが分かっている、それを読み込みたいなんていう状況があるだろうか?(それなら普通にword形式でもデータを持っておけよという話)
パスワードがわからない場合の復号化 (pikepdf)
さて、ではパスワードがわからない時にはどうするか。その中でも最もスマートな解が、stackoverflowに上がっていた。簡単にいうと、pikepdf
を使おうというものである。pikepdf
は、以下のコマンドでインストール可能である。
pip install pikepdf
あとの使い方は簡単で、
import pikepdf pdf = pikepdf.open("unextractable.pdf") pdf.save("extractable.pdf")
とすれば良い。ここで保存したPDFファイルを、PyPDF2
を使って読み込むだけである。
終わりに
英語のPDFを読み込む必要が出てきたので、対応しているツール周りを簡単に調査した。1時間足らずでここまで調査・実行できるので、そこまで知見が転がっていない話ではないのでだろう。。。現場、問題は起きていないが、また問題が発生した場合にはこちらに追記していこう。
ってことで、今回はこちらの曲を聞いてお別れです。
(せーのっ)
\\\ 朝は来る ///
Amelie「朝は来る」Music Video