如何使用PDFMiner从pdf文件中提取表格?

6

我将尝试从pdf文档中提取一些表格信息。
考虑以下输入:

Title 1
some text some text some text some text some text
some text some text some text some text some text

Table Title
| Col1          | Col2    | Col3    |
|---------------|---------|---------|
| val11         | val12   | val13   |
| val21         | val22   | val23   |
| val31         | val32   | val33   |

Title 2
some more text some more text some more text some more text
some more text
some more text some more text some more text some more text

我可以这样获得轮廓/标题:

我可以这样获得轮廓/标题:

path='myFile.pdf'
# Open a PDF file.
fp = open(path, '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, '')
outlines = document.get_outlines()
for (level,title,dest,a,se) in outlines:
    print (level, title)

这给了我:
(1, u'Title 1')
(2, u'Table Title')
(1, u'Title 2')

正好,因为级别与文本层次结构对齐。现在我可以按以下方式提取文本:

if not document.is_extractable:
    raise PDFTextExtractionNotAllowed
# Create a PDF resource manager object that stores shared resources.
rsrcmgr = PDFResourceManager()
# Create a PDF device object.
laparams = LAParams()
device = PDFPageAggregator(rsrcmgr, laparams=laparams)
# Create a PDF interpreter object.
interpreter = PDFPageInterpreter(rsrcmgr, device)
# Process each page contained in the document.
text_from_pdf = open('textFromPdf.txt','w')
for page in PDFPage.create_pages(document):
    interpreter.process_page(page)
    layout = device.get_result()
    for element in layout:
        if isinstance(element, LTTextBox):
            text_from_pdf.write(''.join([i if ord(i) < 128 else ' '
                                            for i in element.get_text()]))

这给了我:

Title 1
some text some text some text some text some text some text some text
some text some text some text some text some text some text some text
Table Title
Col1
val11
val12
val13
Col2
val21
val22
val23
Col3
val31
val32
val33
Title 2
some more text some more text some more text some more text
some more text
some more text some more text some more text some more text

这有点奇怪,因为表格是按列提取的。我能否逐行获取表格?此外,如何确定表格的起始和结束位置?


2
如果您可以逐列提取表格并将其存储到二维“列表”(列表的列表)中,那么您应该能够转置它以使其成为逐行格式。这通常使用内置的zip()函数完成。至于找到表格的结尾,您需要查看是否可以检测到某种格式上的变化。 - martineau
谢谢,但问题是我不知道表格从哪里开始。我的文档中的任何标题都可能表示一个表格。我该怎么知道呢? - AbtPst
1
如果PDF文档只有一个来源,那么表格的构建可能会有一定的模式。如果您能够找出这个模式并监控它,那么您的代码就可以应对这种情况。不幸的是,我认为PDF文件没有任何形式的“表格”元素,因此像这样做可能是您唯一的选择... - martineau
谢谢,明白了。我得根据我的数据制定一种策略。 - AbtPst
2个回答

4
如果你只想从PDF文档中提取表格,那么请看这个答案:如何使用Python从PDF中提取表格作为文本? 从那个答案中,我尝试了tabula-py,对于跨多页PDF的图表表格,它对我很有效。 tabula-py可以正确跳过所有标题和页脚。之前我在同一类型的文档上尝试过PDFMiner,我遇到了你提到的同样的问题,有时甚至更糟。

4

使用camelot从pdf中提取表格


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接