PDFMiner(私はPDFMiner3Kのユースケースを書いた記事の最後に、そこを扱います)

PDFMiner

PDFMiner公式サイト
注:PDFMinerとはPDFMiner3K異なります。あなたのお母さんの詳細については。

概要

PDFは悪です。それはPDF「文書」と呼ばれているが、それは、WordやHTML文書のような何もありません。PDFは、より多くのグラフィック表現のようなものです。PDFの内容は、ディスプレイや紙の上の各正確な位置にものを配置する方法を教えて命令のちょうど束です。ほとんどの場合、そのような文や段落などの論理的な構造を持っていないと、用紙サイズが変更されたとき、それは自分自身を適応させることはできません。PDFMinerの試みは、その位置から推測して、それらの構造の一部を再構成するが、仕事への保証は何もありません。醜い、私は知っています。ここでも、PDFは悪です。

[PDFの内部構造についての技術的な詳細:「PDFを手動からテキスト内容を抽出する方法」(その1) その2) その3) ]

PDFファイルには、Aが大きくて複雑な構造を持っているので、全体としてPDFファイルを解析することは、時間とメモリを消費しています。しかし、必ずしもすべての部分は、ほとんどのPDF処理タスクのために必要とされています。したがってPDFMinerはそれが必要だときにだけのものを解析することです怠惰な構文解析の戦略をとります。パースPDFファイルに、あなたは、少なくとも2つのクラスを使用する必要がありますPDFParserPDFDocumentこれら二つのオブジェクトが互いに関連しています。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()

レイアウトアナライザは返しLTPagePDF文書内の各ページのオブジェクトを。このオブジェクトは、ツリー構造を形成し、ページ内の子オブジェクトが含まれています。図2は、これらのオブジェクト間の関係。


図2.レイアウトオブジェクトとそのツリー構造

LTPage

ページ全体を表します。以下のような子オブジェクトを含むことができLTTextBoxLTFigureLTImageLTRectLTCurveLTLine

LTTextBox

矩形領域に含まれることができるテキストチャンクのグループを表します。このボックスは、幾何学的な分析によって作成され、必ずしもテキストの論理境界を表していないことに注意してください。これは、のリストが含まれLTTextLineたオブジェクトを。get_text()この方法は、テキストの内容を返します。

LTTextLine

リスト含まれているLTChar単一のテキスト行を表すオブジェクトを。文字はテキストの書き込みモードに応じて、どちらかhorizo​​ntalyまたは垂直方向に整列されています。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

ステップ:

  1. ファイル
  2. PDFParser < - ファイル
  3. PDFDocument < - 空
  4. PDFDocument < - > PDFParser
  5. PDFDocument.initialize()< - ""
  6. PDFResourceManager <- 空
  7. LAParams < - 空
  8. PDFPageAggregator < - PDFDocument、LAParams
  9. PDFPageInterpreter < - PDFResourceManager、PDFDevice
  10. PDFPageInterpreter.process_page()< - PDFDocument.get_pages中のページ()
  11. (LTPage)PDFDevice.get_result()
  12. LTPageでGET_TEXT性質を持っているtext_obj要素を探します
  13. 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()

おすすめ

転載: www.cnblogs.com/alohana/p/12238533.html