PDFMiner
PDFMiner公式サイト
注:PDFMiner
とはPDFMiner3K
異なります。あなたのお母さんの詳細については。
概要
PDFは悪です。それはPDF「文書」と呼ばれているが、それは、WordやHTML文書のような何もありません。PDFは、より多くのグラフィック表現のようなものです。PDFの内容は、ディスプレイや紙の上の各正確な位置にものを配置する方法を教えて命令のちょうど束です。ほとんどの場合、そのような文や段落などの論理的な構造を持っていないと、用紙サイズが変更されたとき、それは自分自身を適応させることはできません。PDFMinerの試みは、その位置から推測して、それらの構造の一部を再構成するが、仕事への保証は何もありません。醜い、私は知っています。ここでも、PDFは悪です。
[PDFの内部構造についての技術的な詳細:「PDFを手動からテキスト内容を抽出する方法」(その1) (その2) (その3) ]
PDFファイルには、Aが大きくて複雑な構造を持っているので、全体としてPDFファイルを解析することは、時間とメモリを消費しています。しかし、必ずしもすべての部分は、ほとんどのPDF処理タスクのために必要とされています。したがってPDFMinerはそれが必要だときにだけのものを解析することです怠惰な構文解析の戦略をとります。パースPDFファイルに、あなたは、少なくとも2つのクラスを使用する必要がありますPDFParser
とPDFDocument
。これら二つのオブジェクトが互いに関連しています。PDFParser
ファイルからのデータ、およびフェッチPDFDocument
格納します。また、必要がありますPDFPageInterpreter
ページの内容を処理し、PDFDevice
何が必要にそれを翻訳します。PDFResourceManager
フォントや画像などの共有リソースを格納するために使用されます。
図1に示すPDFMinerのクラス間の関係。
PDFMinerクラス間の関係を図1
基本的な使い方
PDFファイルを解析するための一般的な方法は以下の通りであります:
from pdfminer.pdfparser import PDFParser
from pdfminer.pdfdocument import PDFDocument
from pdfminer.pdfpage import PDFPage
from pdfminer.pdfpage import PDFTextExtractionNotAllowed
from pdfminer.pdfinterp import PDFResourceManager
from pdfminer.pdfinterp import PDFPageInterpreter
from pdfminer.pdfdevice import PDFDevice
# Open a PDF file.
fp = open('mypdf.pdf', 'rb')
# Create a PDF parser object associated with the file object.
parser = PDFParser(fp)
# Create a PDF document object that stores the document structure.
# Supply the password for initialization.
document = PDFDocument(parser, password)
# Check if the document allows text extraction. If not, abort.
if not document.is_extractable:
raise PDFTextExtractionNotAllowed
# Create a PDF resource manager object that stores shared resources.
rsrcmgr = PDFResourceManager()
# Create a PDF device object.
device = PDFDevice(rsrcmgr)
# Create a PDF interpreter object.
interpreter = PDFPageInterpreter(rsrcmgr, device)
# Process each page contained in the document.
for page in PDFPage.create_pages(document):
interpreter.process_page(page)
レイアウト解析を実行します
ここでは、レイアウト解析機能を使用するための典型的な方法は次のとおりです。
from pdfminer.layout import LAParams
from pdfminer.converter import PDFPageAggregator
# Set parameters for analysis.
laparams = LAParams()
# Create a PDF page aggregator object.
device = PDFPageAggregator(rsrcmgr, laparams=laparams)
interpreter = PDFPageInterpreter(rsrcmgr, device)
for page in PDFPage.create_pages(document):
interpreter.process_page(page)
# receive the LTPage object for the page.
layout = device.get_result()
レイアウトアナライザは返しLTPage
PDF文書内の各ページのオブジェクトを。このオブジェクトは、ツリー構造を形成し、ページ内の子オブジェクトが含まれています。図2は、これらのオブジェクト間の関係。
図2.レイアウトオブジェクトとそのツリー構造
LTPage
ページ全体を表します。以下のような子オブジェクトを含むことができLTTextBox
、LTFigure
、LTImage
、LTRect
、LTCurve
とLTLine
。
LTTextBox
矩形領域に含まれることができるテキストチャンクのグループを表します。このボックスは、幾何学的な分析によって作成され、必ずしもテキストの論理境界を表していないことに注意してください。これは、のリストが含まれLTTextLine
たオブジェクトを。get_text()
この方法は、テキストの内容を返します。
LTTextLine
リスト含まれているLTChar
単一のテキスト行を表すオブジェクトを。文字はテキストの書き込みモードに応じて、どちらかhorizontalyまたは垂直方向に整列されています。get_text()
この方法は、テキストの内容を返します。
LTChar
LTAnno
Unicode文字列としてテキスト内の実際の文字を表します。ながら、そのノートLTChar
の目的は、実際の境界を有し、LTAnno
これらは2つの文字間の関係(例えば、空間)に係るレイアウトアナライザによって挿入「仮想」文字であるように、しないオブジェクト。
LTFigure
PDFフォームのオブジェクトが使用する領域を表します。PDFフォームは、ページ内にさらに別のPDFドキュメントを埋め込むことにより、本図形や画像に使用することができます。ことに注意してくださいLTFigure
オブジェクトを再帰的に表示することができます。
LTImage
画像オブジェクトを表します。埋め込まれた画像は、JPEGや他のフォーマットにすることができますが、現在はPDFMinerは、グラフィカルオブジェクトに多くの注意を払っていません。
LTLine
一本の直線を表します。テキストや図形を分離するために使用することができます。
LTRect
矩形を表します。別の絵や図形をフレーミングするために使用することができます。
LTCurve
一般的なベジエ曲線を表します。
また、チェックアウトデニスPapathanasiouすることで、より完全な例を。
目次を取得
PDFMinerは内容(「アウトライン」)のドキュメントのテーブルにアクセスするための機能を提供します。
from pdfminer.pdfparser import PDFParser
from pdfminer.pdfdocument import PDFDocument
# Open a PDF document.
fp = open('mypdf.pdf', 'rb')
parser = PDFParser(fp)
document = PDFDocument(parser, password)
# Get the outlines of the document.
outlines = document.get_outlines()
for (level,title,dest,a,se) in outlines:
print (level, title)
他はページ番号とページ内の物理的な位置を使用しながら、いくつかのPDF文書は、宛先としてページ番号を使用します。PDFの論理構造を持っていない、そしてそれは外部から任意のページ内のオブジェクトを参照する方法を提供していないので、これらの宛先が言及されているテキストの一部を正確に伝える方法はありません。
拡張機能
あなたは拡張することができますPDFPageInterpreter
し、PDFDevice
その他の情報を取得/異なり、それらを処理するためにクラス。
PDFファイルを解析しPDF3K
ステップ:
- ファイル
- PDFParser < - ファイル
- PDFDocument < - 空
- PDFDocument < - > PDFParser
- PDFDocument.initialize()< - ""
- PDFResourceManager <- 空
- LAParams < - 空
- PDFPageAggregator < - PDFDocument、LAParams
- PDFPageInterpreter < - PDFResourceManager、PDFDevice
- PDFPageInterpreter.process_page()< - PDFDocument.get_pages中のページ()
- (LTPage)PDFDevice.get_result()
- LTPageでGET_TEXT性質を持っているtext_obj要素を探します
- text_obj.get_text()
import logging
from urllib.request import urlopen
from pdfminer.converter import PDFPageAggregator
from pdfminer.layout import LAParams
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.pdfparser import PDFParser, PDFDocument
logging.Logger.propagate = False
logging.getLogger().setLevel(logging.ERROR)
fp = open('template/pdftest.pdf', 'rb')
# 在线
# fp = urlopen('http://---/---.pdf')
# 创建一个与文档关联的解析器
parser = PDFParser(fp)
# PDF文档对象
doc = PDFDocument()
# 链接解析器和文档对象
parser.set_document(doc)
doc.set_parser(parser)
# 初始化文档
doc.initialize("")
# 创建DPF资源管理器
resource = PDFResourceManager()
# 参数分析器
laparam = LAParams()
# 聚合器
device = PDFPageAggregator(resource, laparams=laparam)
# 创建页面解析器
interpreter = PDFPageInterpreter(resource, device)
# 使用文档对象从pdf中读取内容
for page in doc.get_pages():
# 使用页面解析器
interpreter.process_page(page)
# 使用聚合器获取内容
layout = device.get_result()
for text_obj in layout:
# 判断是否有get_text属性
if hasattr(text_obj, 'get_text'):
print(text_obj.get_text())
PDFMiner3K例
#!C:\ProgramData\Anaconda3\python.exe
# coding=utf-8
import sys
from pdfminer.converter import PDFPageAggregator
from pdfminer.layout import LAParams
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.pdfparser import PDFParser, PDFDocument
def find_in_pdf():
if len(sys.argv) < 3:
print("usage: python pypdf.py pdf_file_name destination_string show_contents(y/n)")
return 1
pdf_file_name = sys.argv[1]
dest_str = sys.argv[2]
if len(sys.argv) == 4:
show_contents = sys.argv[3]
else:
show_contents = 'y'
fp = open(pdf_file_name, 'rb')
parser = PDFParser(fp)
doc = PDFDocument()
parser.set_document(doc)
doc.set_parser(parser)
doc.initialize("")
resource = PDFResourceManager()
laparam = LAParams()
device = PDFPageAggregator(resource, laparams = laparam)
interpreter = PDFPageInterpreter(resource, device)
count = 0
page_num = 0
block_num = 0
print("\n**block序号仅供参考**\n")
for page in doc.get_pages():
page_num += 1
interpreter.process_page(page)
layout = device.get_result()
for out in layout:
block_num += 1
if hasattr(out, 'get_text'):
text = out.get_text()
if text.find(dest_str) != -1:
count += 1
print("#page ", "{:4}".format(page_num), ", #block ", "{:3}".format(block_num), sep = '', end = '')
if (show_contents == 'y') | (show_contents == 'Y'):
print(": ", text, sep = '')
else:
print()
block_num = 0
print("------", count, "positions in all. ------")
if __name__ == "__main__":
find_in_pdf()