这是一个可以复制和粘贴的示例,它列出了 PDF 中每个文本块的左上角,我认为它应该适用于任何不包含具有文本的“Form XObjects”的 PDF其中:
from pdfminer.layout import LAParams, LTTextBox
from pdfminer.pdfpage import PDFPage
from pdfminer.pdfinterp import PDFResourceManager
from pdfminer.pdfinterp import PDFPageInterpreter
from pdfminer.converter import PDFPageAggregator
fp = open('yourpdf.pdf', 'rb')
rsrcmgr = PDFResourceManager()
laparams = LAParams()
device = PDFPageAggregator(rsrcmgr, laparams=laparams)
interpreter = PDFPageInterpreter(rsrcmgr, device)
pages = PDFPage.get_pages(fp)
for page in pages:
print('Processing next page...')
interpreter.process_page(page)
layout = device.get_result()
for lobj in layout:
if isinstance(lobj, LTTextBox):
x, y, text = lobj.bbox[0], lobj.bbox[3], lobj.get_text()
print('At %r is text: %s' % ((x, y), text))
以上代码基于 PDFMiner 文档中的 Performing Layout Analysis 示例,以及 pnj (https://stackoverflow.com/a/22898159/1709587) 和 Matt Swain (https://stackoverflow.com/a/25262470/1709587) 的示例。我对这些之前的示例进行了一些更改:
- 我使用
PDFPage.get_pages(),这是创建文档的简写,检查它is_extractable,并将它传递给PDFPage.create_pages()
- 我懒得处理
LTFigures,因为 PDFMiner 目前无论如何都无法干净地处理其中的文本。
LAParams 允许您设置一些参数来控制 PDF 中的单个字符如何被 PDFMiner 神奇地分组为行和文本框。如果您对这样的分组是一件必须发生的事情感到惊讶,那么pdf2txt docs 是合理的:
在实际的 PDF 文件中,文本部分可能会在其运行过程中被分成几个块,具体取决于创作软件。因此,文本提取需要拼接文本块。
LAParams 的参数与大多数 PDFMiner 一样,是未记录的,但您可以通过in the source code 或在 Python shell 中调用 help(LAParams) 来查看它们。 一些参数的含义在https://pdfminer-docs.readthedocs.io/pdfminer_index.html#pdf2txt-py给出,因为它们也可以在命令行中作为参数传递给pdf2text。
上面的layout 对象是一个LTPage,它是“布局对象”的可迭代对象。这些布局对象中的每一个都可以是以下类型之一...
LTTextBox
LTFigure
LTImage
LTLine
LTRect
... 或其子类。 (特别是,您的文本框可能都是LTTextBoxHorizontals。)
文档中的这张图片显示了LTPage 结构的更多细节:
上述每种类型都有一个.bbox 属性,其中包含一个 (x0, y0, x1, y1) 元组,分别包含对象的左、下、右和上坐标。 y 坐标表示为到页面底部 的距离。如果您更方便地使用从上到下的 y 轴,您可以从页面的 .mediabox 的高度中减去它们:
x0, y0_orig, x1, y1_orig = some_lobj.bbox
y0 = page.mediabox[3] - y1_orig
y1 = page.mediabox[3] - y0_orig
除了bbox,LTTextBoxes 还有一个.get_text() 方法,如上所示,将其文本内容作为字符串返回。请注意,每个LTTextBox 都是LTChars(由PDF 显式绘制的字符,带有bbox)和LTAnnos(PDFMiner 添加到基于文本框内容的字符串表示形式的额外空格)的集合字符被画得很远;这些没有bbox)。
这个答案开头的代码示例结合了这两个属性来显示每个文本块的坐标。
最后,值得注意的是,与上面引用的其他 Stack Overflow 答案不同,我不费心递归到 LTFigures。尽管LTFigures 可以包含文本,但PDFMiner 似乎无法将该文本分组到LTTextBoxes(您可以尝试使用https://stackoverflow.com/a/27104504/1709587 的示例PDF),而是生成一个直接包含@987654362 的LTFigure @对象。原则上,您可以弄清楚如何将这些拼凑成一个字符串,但 PDFMiner(截至 20181108 版)无法为您完成。
但希望您需要解析的 PDF 不使用带有文本的 Form XObjects,因此此警告不适用于您。