4

Camelot 是一个很棒的 Python 库,可以从 pdf 文件中提取表格作为数据框。但是,我正在寻找一种解决方案,该解决方案还可以返回写在表格正上方的表格描述文本。

我用于从 pdf 中提取表格的代码是这样的:

import camelot
tables = camelot.read_pdf('test.pdf', pages='all',lattice=True, suppress_stdout = True)

我想提取表格上方的文字,即THE PARTICULARS,如下图所示。

对我来说最好的方法是什么?感谢任何帮助。谢谢你

在此处输入图像描述

4

2 回答 2

3

您可以直接创建 Lattice 解析器

            parser = Lattice(**kwargs)
            for p in pages:
                t = parser.extract_tables(p, suppress_stdout=suppress_stdout,
                                          layout_kwargs=layout_kwargs)
                tables.extend(t)

然后你就可以访问parser.layout其中包含页面中的所有组件了。这些组件都有bbox (x0, y0, x1, y1),提取的表也有一个bbox对象。您可以在其顶部找到最接近表格的组件并提取文本。

于 2019-10-09T09:58:33.603 回答
1

这是我非常糟糕的实现,只是为了让人们可以大笑并受到启发去做一个更好的,并为伟大的骆驼包做出贡献:)

注意事项:

  • 仅适用于非旋转表
  • 这是一个启发式
  • 代码不好
# Helper methods for _bbox
def top_mid(bbox):
    return ((bbox[0]+bbox[2])/2, bbox[3])

def bottom_mid(bbox):
    return ((bbox[0]+bbox[2])/2, bbox[1])

def distance(p1, p2):
    return math.sqrt((p1[0]-p2[0])**2 + (p1[1]-p2[1])**2)

def get_closest_text(table, htext_objs):
    min_distance = 999  # Cause 9's are big :)
    best_guess = None
    table_mid = top_mid(table._bbox)  # Middle of the TOP of the table
    for obj in htext_objs:
        text_mid = bottom_mid(obj.bbox)  # Middle of the BOTTOM of the text
        d = distance(text_mid, table_mid)
        if d < min_distance:
            best_guess = obj.get_text().strip()
            min_distance = d
    return best_guess

def get_tables_and_titles(pdf_filename):
    """Here's my hacky code for grabbing tables and guessing at their titles"""
    my_handler = PDFHandler(pdf_filename)  # from camelot.handlers import PDFHandler
    tables = camelot.read_pdf(pdf_filename, pages='2,3,4')
    print('Extracting {:d} tables...'.format(tables.n))
    titles = []
    with camelot.utils.TemporaryDirectory() as tempdir:
        for table in tables:
            my_handler._save_page(pdf_filename, table.page, tempdir)
            tmp_file_path = os.path.join(tempdir, f'page-{table.page}.pdf')
            layout, dim = camelot.utils.get_page_layout(tmp_file_path)
            htext_objs = camelot.utils.get_text_objects(layout, ltype="horizontal_text")
            titles.append(get_closest_text(table, htext_objs))  # Might be None

    return titles, tables

见:https ://github.com/atlanhq/camelot/issues/395

于 2021-02-17T01:55:05.120 回答