所以我在我编写的 pdf 提取脚本中遇到了两件事。
首先,脚本没有选取最后一列“序列号” 我已经将我感兴趣的区域以及我需要的明确的垂直策略线框起来了
正如您从屏幕截图中看到的,垂直线整齐地划分了列,这在 pdf 的所有页面上都是如此。方框区域还捕获了所有页面上我想要的所有内容。
我的脚本在这里:
import pdfplumber
pdf_file = r"C:\Users\xxxx\Downloads\Active Aircraft Register.pdf"
box = (0, 35, 980, 565)
explicit_vertical_lines = [18, 57, 127, 325, 518, 713, 830, 920, 984]
all_tables = []
with pdfplumber.open(pdf_file) as pdf:
for page in pdf.pages:
cropped_page = page.crop(bbox=box)
table = cropped_page.extract_table(table_settings={
"vertical_strategy": "explicit",
"explicit_vertical_lines": explicit_vertical_lines,
"horizontal_strategy": "text",
})
if table:
all_tables.extend(table)
# Check if we have any tables extracted
if not all_tables:
print("No tables found in the PDF.")
else:
for row in all_tables[:10]:
print(row)
第二个问题是,一旦脚本完成提取,如果任何行中有一个多行单元格(例如地址或类型变体),它就会用空格单独放置每一行,有没有办法让它全部放在一个单元格上线?
我正在使用的 PDF 文件可以在此处下载来测试脚本:https://www.caacayman.com/wp-content/uploads/pdf/Active%20Aircraft%20Register.pdf
pdf水管工0.11.4
使用水平策略
'text'
提取时,请务必记住 pdfplumber
会为每条检测到的线创建新的水平边缘。这些边缘从最左边字符的水平位置 x0
开始,到边界框内最右边字符的 x1
结束。如果定义的垂直边距这些新创建的水平边的端点太远,则在后续步骤中可能无法将它们检测为相交。这就是为什么您可能会丢失最右边的列 - explicit_vertical_lines
中的最后一个垂直位置不与由字线构建的水平边缘相交。
为了解决这个问题,我们可以将 intersection_x_tolerance 参数增加到一个值来补偿水平边缘和垂直线之间的间隙,或者重新定义最右边垂直线的位置,使其与屏幕上的文本对齐。对了,像这样:
explicit_vertical_lines[-1] = max(c['x1'] for c in page.chars)
有关更多示例,您可以参考 此案例,它提供了更多详细信息,或者 这个顶部有丢失行的案例,它源于类似的问题。
但是,我想建议一种同时解决这两个问题的替代方法。由于源文档已被修改,原始链接不再相关,我将根据提供的屏幕截图进行解释。
如图所示,每个单元格中的数据与顶部垂直对齐,并且第一列中的每个单元格只有一行。因此,我们可以使用第一列中的单词来识别每个单元格的顶行。此方法涉及裁剪页面以隔离列、提取行/单词,并使用它们的
'top'
值作为 explicit_horizontal_lines
的点。这是我们可以使用的代码示例:
bbox = (0, 35, 980, 565) # data bounding box
first_col_bbox = [explicit_horizontal_lines[0], bbox[1],
explicit_horizontal_lines[1], bbox[3]]
words = page.crop(first_col_bbox).extract_words()
explicit_horizontal_lines = *(w['top'] for w in words), bbox[3] # we neen bbox[3] at the end,
# which is the bottom of the data area,
# to extract the row at the very bottom
settings = {
'horizontal_strategy': 'explicit',
'vertical_strategy': 'explicit',
'explicit_vertical_lines': explicit_vertical_lines,
'explicit_horizontal_lines': explicit_horizontal_lines,
}
table = page.crop(bbox).extract_table(settings)