PythonでPDFを処理できるpdfminer3kの使い方メモ
PythonでPDFを処理できるpdfminer3kの使い方メモ
pdfminerを使うとpdfをパース・解析(情報を取得)できる(pdfのスクレイピング的なことができる).
環境
-
Windows10
-
python 3.5.3
-
pdfminer3k 1.3.1
-
pdfminerのモジュールの種類
オリジナルのpdfminerはpython2系デノミ使える.
種類 | pythonのversion | 更新 |
---|---|---|
pdfminer(オリジナル) | 2系 | 最新版2014年 |
pdfminer.six | 2・3系対応 | 2017年の今も更新されている |
pdfminer3k | 3系 | 最新版2015年 |
注意点:どのモジュールもimportするときのnameはpdfminer
なので競合注意.
これからpdfminerを始める人は,「pdfminer.six」がよさげ(今も更新されているので).
install
上記の3つはpip からインストールできる.
> pip search pdfminer3k
pdfminer3k (1.3.1) - PDF parser and analyzer
> pip install pdfminer3k
pdfminerの処理の流れ
必要なオブジェクトがけっこうあるので,最初とっつきにくい. が,オブジェクトごとに役割がある.
-
PDFファイルを開き,PDFのファイルオブジェクトを作成
-
PDFParser
オブジェクトを作って,1.のファイルオブジェクトを投げる,`PDFParser`はファイルからデータをfetchする. -
PDFDocument
オブジェクトにパーサーから読まれたデータが保存される(まだ各ページの内容(page content)の処理はしていない). -
PDFPageInterpreter
オブジェクトを作成.PDFDocument
から任意のページのオブジェクトPagePDF
を投げると,page contentが処理される. -
PDFDevice
オブジェクトに,そのページのテキストなどのデータが保存される.
PDFResourceManager
オブジェクトは,シェアされるリソース( fonts や imageなど)を保存するのにつかわれる.
pdfminer3kのサブモジュールとクラスの位置
pdfminer(2系オリジナル)とpdfminer 3kのクラスの位置が異なるので注意.
# pdfminer3kの場合
from pdfminer.pdfparser import PDFParser
from pdfminer.pdfparser import PDFDocument
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.pdfparser import PDFPage
from pdfminer.pdfparser import PDFException
from pdfminer.pdfdevice import PDFDevice
from pdfminer.converter import PDFPageAggregator
from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams
example1:PDFファイルの各ページのPDFPage
オブジェクトの取得
この例では,PDFPageInterpreter
とPDFDevice
は使わない.
# 一括処理
from pdfminer.pdfparser import PDFParser
from pdfminer.pdfparser import PDFDocument
from pdfminer.pdfparser import PDFPage
from pdfminer.pdfparser import PDFException
from pdfminer.pdfinterp import PDFResourceManager
from pdfminer.pdfinterp import PDFPageInterpreter
from pdfminer.pdfdevice import PDFDevice
# Open a PDF file.
fp = open('.pdf', 'rb')
# Create a PDF parser object associated with the file object.
parser = PDFParser(fp)
document = PDFDocument()
parser.set_document(document) # set document to parser
# Create a PDF document object that stores the document structure.
# Supply the password for initialization.
password="" # pdfを開くときのパスワード
document.set_parser(parser) # set parser to document
document.initialize(password)
# Check if the document allows text extraction. If not, abort.
if not document.is_extractable:
raise PDFException
# Process each page contained in the document.
for page in document.get_pages():
print(page)
> , 'ExtGState': , 'ProcSet': [/PDF, /Text]}, MediaBox=[0, 0, 595.28, 841.89]>
PDFPage
をprint
すると, FontやMediaBoxなどの情報が見れる.
注意:Encryption Errorが出る場合
document.initialize()
でEncryption Error
が出る場合,PDFに保護がかかっている可能がある.なので保護をqpdfなどで解除する必要がある.
参考
example2: レイアウト解析
Webスクレイピングでいうところのhtmlのタグ構造を見るのと同じように, PDFのそのページの構造が見れる.
今回の例は,PDF中の1ページ目中の複数ある LTTextBoxHorizontal
から文字列を抽出する.
# 一括処理
from pdfminer.pdfparser import PDFParser
from pdfminer.pdfparser import PDFDocument
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.pdfparser import PDFPage
from pdfminer.pdfdevice import PDFDevice
from pdfminer.converter import PDFPageAggregator
from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams
from pdfminer.layout import LTTextBoxHorizontal
# Open a PDF file.
fp = open('epack_shipping_dec.pdf', 'rb')
# Create a PDF parser object associated with the file object.
parser = PDFParser(fp)
document = PDFDocument()
parser.set_document(document)
# Create a PDF document object that stores the document structure.
# Supply the password for initialization.
password=""
document.set_parser(parser)
document.initialize(password)
# Create a PDF resource manager object that stores shared resources.
rsrcmgr = PDFResourceManager()
# Set parameters for analysis.
laparams = LAParams()
# Create a PDF page aggregator object.
device = PDFPageAggregator(rsrcmgr, laparams=laparams)
interpreter = PDFPageInterpreter(rsrcmgr, device)
pages = list(document.get_pages())
page_1 = pages[0] # 1st page
page_1
# interpreter page1
interpreter.process_page(page_1)
# receive the LTPage object for the page.
# layoutの中にページを構成する要素(LTTextBoxHorizontalなど)が入っている
layout = device.get_result()
# print(layout)
for l in layout:
# print(l) # l is object
if isinstance(l, LTTextBoxHorizontal):
print(l.get_text()) # オブジェクト中のtextのみ抽出
参考リンク