初学者です。
お力添えのほど、よろしくお願いいたします。
実現したいこと
pdfの中で、指定した範囲内にあるテキストを抽出したいと考えています。
発生している問題・エラーメッセージ
テキストの文字が1ブロックになっている場合(表現が適切か分かりませんが)は読み取れますが、
複数に分かれている場合に出力できません。(文末に補足の画像を掲載しました)
コード from pdfminer.high_level import extract_text from pdfminer.layout import LAParams, LTTextBoxHorizontal, LTTextLineHorizontal from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter from pdfminer.pdfpage import PDFPage from pdfminer.converter import PDFPageAggregator x1, y1, x2, y2 = 100,100,200,200 #範囲を指定 with open('/rename/image.pdf', 'rb') as pdf_file: # PDFファイルを開く resource_manager = PDFResourceManager() # PDFMinerのリソースマネージャーを初期化 laparams = LAParams() device = PDFPageAggregator(resource_manager, laparams=laparams) interpreter = PDFPageInterpreter(resource_manager, device) for page in PDFPage.get_pages(pdf_file): # ページごとに処理 interpreter.process_page(page) layout = device.get_result() for lt_obj in layout: # ページ内のテキストをチェック if isinstance(lt_obj, (LTTextBoxHorizontal, LTTextLineHorizontal)): x, y, _, _ = lt_obj.bbox if x1 <= x <= x2 and y1 <= y <= y2: text = lt_obj.get_text().strip() print(text) ### 試したこと 検出された複数のテキストに対して、OCRさせたい両端の座標を入力すればよいのではないかと想定して試しましたが、 結果はダメでした。(補足情報欄にイメージを掲載しました) なお、pdf内のテキストの座標は、以下のコードを実行して取得しました。 python コード 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.layout import LAParams from pdfminer.converter import PDFPageAggregator # PDFファイルのパスを指定 pdf_file_path = "/image.pdf" # PDFファイルをバイナリ形式で開く with open(pdf_file_path, 'rb') as fp: # PDFパーサーを作成 parser = PDFParser(fp) # PDFドキュメントを作成 document = PDFDocument(parser) # パスワードが設定されていないことを確認 if not document.is_extractable: raise PDFTextExtractionNotAllowed # PDFリソースマネージャーを作成 rsrcmgr = PDFResourceManager() # ページの解析パラメータを設定 laparams = LAParams() # ページの集約器を作成 device = PDFPageAggregator(rsrcmgr, laparams=laparams) # ページの解析器を作成 interpreter = PDFPageInterpreter(rsrcmgr, device) # 全ページに対して処理を行う for page in PDFPage.create_pages(document): # ページの内容を解析 interpreter.process_page(page) # 解析結果からレイアウトを取得 layout = device.get_result() # レイアウトからテキストの座標を取得し表示 for element in layout: if hasattr(element, "get_text"): print("Text: ", element.get_text()) print("Position: ", element.bbox) 
提示コードがどこまで意図したとおりに動作しているか?
たとえば「ページ内のテキストをチェック」において
- isinstanceは意図した型チェックができているか
- x,yには意図した座標が入っているか
といったことをprint文を挿入するなどして確認した結果を記載すると
回答得られやすくなるかと思います。
can110様
アドバイスありがとうございます
そのようにいたします。
can110様
アドバイスいただいた通りコードを見直し、文末にif文を追加することで実現できました。
ありがとうございました。
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.layout import LAParams
from pdfminer.converter import PDFPageAggregator
# PDFファイルのパスを指定
pdf_file_path = "/sample.pdf"
x_left_bottom_val = 390
y_left_bottom_val = 620
x_right_top_val = 520
y_right_top_val = 740
# PDFファイルをバイナリ形式で開く
with open(pdf_file_path, 'rb') as fp:
# PDFパーサーを作成
parser = PDFParser(fp)
# PDFドキュメントを作成
document = PDFDocument(parser)
# パスワードが設定されていないことを確認
if not document.is_extractable:
raise PDFTextExtractionNotAllowed
# PDFリソースマネージャーを作成
rsrcmgr = PDFResourceManager()
# ページの解析パラメータを設定
laparams = LAParams()
# ページの集約器を作成
device = PDFPageAggregator(rsrcmgr, laparams=laparams)
# ページの解析器を作成
interpreter = PDFPageInterpreter(rsrcmgr, device)
# 全ページに対して処理を行う
for page in PDFPage.create_pages(document):
# ページの内容を解析
interpreter.process_page(page)
# 解析結果からレイアウトを取得
layout = device.get_result()
# レイアウトからテキストの座標を取得し表示
for element in layout:
if hasattr(element, "get_text"):
x1, y1, x2, y2 = element.bbox
if x1 > x_left_bottom_val and y1 > y_left_bottom_val and x2 < x_right_top_val and y2 < y_right_top_val:
print("Text: ", element.get_text())
# print("Position: ", element.bbox)

回答1件
あなたの回答
tips
プレビュー