ラベル PDFMiner の投稿を表示しています。 すべての投稿を表示
ラベル PDFMiner の投稿を表示しています。 すべての投稿を表示

2018年6月4日月曜日

修正:PDFMinerでpdfからtxtを抽出する。(python、PDFMiner.six、エネルギー基本計画)

2018年6月4日更新:誤りがあったため、修正しました。
----

エネルギー基本計画の改訂案(第5次エネルギー基本計画(案))が公表されました。

エネルギー基本計画(案)平成30年5月16日
http://www.enecho.meti.go.jp/committee/council/basic_policy_subcommittee/pdf/basic_policy_subcommittee_002.pdf

今回はこのpdfからtxtを抽出したいと思います。

使うのはPDFMiner.sixです。PDFMinerには他にもバージョンなどがあるようですが、pdfminer.sixはpython2/3系共通であり、現在も更新されているということでこれにしました。

github:pdfminer/pdfminer.six

検索するとPDFMinerを使ったコードがいろいろ出てくるのですが、バージョンが違うためかほとんどがエラーとなりました。下記のページが大変参考になりました。

アラカン"BOKU"のITな日常:PDF形式で受取り、テキストデータを抜いて使うのは現実的な選択肢になるのか?(pdfminer.six)

インストールはpipで入ります。
!pip install pdfminer.six

インストールすると、pdf2txt.pyというツールも保存されます。Anacondaを使っている場合は、Anacondaフォルダ > Scriptフォルダに入っているはずです。
このファイルをテキストに変換したいpdfと同じフォルダに保存します。

今回は前述のエネルギー基本計画(案)をenerg.pdfとしてダウンロード・保存したファイルを使います。

Jupyter notebookでのpdf2txt.pyの実行
%run pdf2txt.py energy.pdf

jupyter notebookでスクリプトを実行する場合は、%runを付けます。これで、pdfからテキストを抽出して画面上に出力されます。

出力をtxtファイルとして保存する場合は、-0 のオプションを付けてoutputファイルを指定します。
%run pdf2txt.py -o energy.txt energy.pdf

出力(一部)
はじめに 

2011年3月の東日本大震災及び東京電力福島第一原子力発電所事故を受
けて、政府は、2014年4月、2030年を念頭に、第4次エネルギー基本計
画を策定し、原発依存度の低減、化石資源依存度の低減、再生可能エネルギーの
拡大を打ち出した。 
第4次エネルギー基本計画の策定から4年、2030年の計画の見直しのみな

らず、2050年を見据えたパリ協定への対応、より長期には化石資源枯渇に備

えた超長期の対応、変化するエネルギー情勢への対応など、今一度、我が国がそ

のエネルギー選択を構想すべき時期に来ている。このため、今回のエネルギー基

本計画の見直しは、2030年の長期エネルギー需給見通し(2015年7月経

済産業省決定。以下「エネルギーミックス」という。)の実現と2050年を見

据えたシナリオの設計で構成することとした。 

妙なところに改行が入ったり、空白が入ったりしています。ちょっと分かりにくいですが、各行の最後にも半角スペースが入っています。

これでは使いにくいので、pdf2txt.pyを使うのではなく、pythonで抽出してみます。

いろいろ調べていたのですが、PDFMinerは非常に高機能なツールのようですが、高機能なために分かりにくくなっている気がします。今回はシンプルに最低限のコードでテキスト化することを目指します。

参考にしたのは、前述のブログ記事と下記の質問サイトのコードです。

stackoverflow
How do I use pdfminer as a library

コード

from pdfminer.pdfparser import PDFParser, PDFDocument
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import TextConverter
#from pdfminer.layout import LAParams

import urllib
import io

fp = urllib.request.urlopen('http://www.enecho.meti.go.jp/committee/council/basic_policy_subcommittee/pdf/basic_policy_subcommittee_002.pdf')
retstr = io.StringIO()

parser = PDFParser(fp)
doc = PDFDocument()
parser.set_document(doc)
doc.set_parser(parser)

rsrcmgr = PDFResourceManager()
device = TextConverter(rsrcmgr, retstr)
interpreter = PDFPageInterpreter(rsrcmgr, device)

for page in doc.get_pages():
    interpreter.process_page(page)

fp.close()
device.close()
    
str = retstr.getvalue()

retstr.close()

str

urllibを使って、インターネット上のpdfを直接読み込んでいます。

パラメーター指定はしないので、layoutのインポートはコメントアウトしています。PDFドキュメントの作成と初期化、リソースマネージャ、デバイス、インタープリターを指定して、forループでページ読み込みテキスト抽出、getvalueでテキストを全て読み出すようです(よく分かっていません)。

このコードでは全てのページからテキストを抽出します。縦書きには対応してません。(layoutで指定が必要)

出力(一部)
はじめに 2011年3月の東日本大震災及び東京電力福島第一原子力発電所事故を受けて、政府は、2014年4月、2030年を念頭に、第4次エネルギー基本計画を策定し、原発依存度の低減、化石資源依存度の低減、再生可能エネルギーの拡大を打ち出した。 第4次エネルギー基本計画の策定から4年、2030年の計画の見直しのみならず、2050年を見据えたパリ協定への対応、より長期には化石資源枯渇に備えた超長期の対応、変化するエネルギー情勢への対応など、今一度、我が国がそのエネルギー選択を構想すべき時期に来ている。このため、今回のエネルギー基本計画の見直しは、2030年の長期エネルギー需給見通し(2015年7月経済産業省決定。以下「エネルギーミックス」という。)の実現と2050年を見据えたシナリオの設計で構成することとした。

改行、空白文字が消えた状態でテキスト抽出できました。通常の(必要な)改行も消えているので若干読みにくいです。

ここでは表示されていませんが、ページ番号が ¥x0c 7 という形式で入っています。この辺りもPDFMinerの設定で変更できるのかもしれません。

今回試したエネルギー基本計画のpdfは単純な文章ファイルなので比較的簡単にテキスト抽出ができましたが、複雑な段組などが入ると難しくなりそうです。逆に複雑なものほど、PDFMinerの本領発揮なのかもしれません。

参考:
資源エネルギー庁:エネルギー基本計画について
http://www.enecho.meti.go.jp/category/others/basic_plan/

github:pdfminer/pdfminer.six
https://github.com/pdfminer/pdfminer.six
PDFMiner HP
https://www.unixuser.org/~euske/python/pdfminer/index.html
アラカン"BOKU"のITな日常:PDF形式で受取り、テキストデータを抜いて使うのは現実的な選択肢になるのか?(pdfminer.six)
http://arakan-pgm-ai.hatenablog.com/entry/2018/01/07/080000
stackoverflow:How do I use pdfminer as a library
https://stackoverflow.com/questions/5725278/how-do-i-use-pdfminer-as-a-library
//SyntaxHighlighter CDNより https://cdnjs.com/libraries/SyntaxHighlighter // 対応言語