Camelot是一个很棒的Python库,可以从pdf文件中提取表作为数据框。但是,我正在寻找一种解决方案,该解决方案还可以返回表格正上方的表格描述文本。
我用于从pdf中提取表格的代码是这样的:
import camelot
tables = camelot.read_pdf('test.pdf', pages='all',lattice=True, suppress_stdout = True)
我想提取写在表格上方的文本,即具体,如下图所示。
对我来说,什么是最好的方法?感谢您的帮助。谢谢
答案 0 :(得分:1)
您可以直接创建莱迪思解析器
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
对象。您可以找到最接近表格顶部的组件,然后提取文本。
答案 1 :(得分:1)
这是我非常糟糕的实现,只是为了让某人可以笑并受到启发去做更好的并为伟大的camelot 包做出贡献:)
注意事项:
# 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