如何提取文本和表格pdfplumber
How to extract texts and tables pdfplumber
使用 pdfplumber 库,您可以提取 PDF 页面的文本,也可以从 pdf 页面提取表格。
问题是我似乎找不到提取文本 和 表格的方法。本质上,如果pdf是这样格式化的:
text1
tablename
___________
| Header 1 |
------------
| row 1 |
------------
text 2
我希望输出为:
["text 1",
"table name",
[["header 1"], ["row 1"]],
"text 2"]
在此示例中,您可以 运行 extract_text 来自 pdfplumber:
with pdfplumber.open("example.pdf") as pdf:
for page in pdf.pages:
page.extract_text()
但这会将文本和表格提取为文本。您可以 运行 extract_tables,但这只会给您表格。我需要一种同时提取文本和表格的方法。
这是否以某种我不理解的方式内置到库中?如果不是,这可能吗?
编辑:已回答
这直接来自已接受的答案,并稍作调整以修复它。非常感谢!
def check_bboxes(word, table_bbox):
"""
Check whether word is inside a table bbox.
"""
l = word['x0'], word['top'], word['x1'], word['bottom']
r = table_bbox
return l[0] > r[0] and l[1] > r[1] and l[2] < r[2] and l[3] < r[3]
tables = page.find_tables()
table_bboxes = [i.bbox for i in tables]
tables = [{'table': i.extract(), 'top': i.bbox[1]} for i in tables]
non_table_words = [word for word in page.extract_words() if not any(
[check_bboxes(word, table_bbox) for table_bbox in table_bboxes])]
lines = []
for cluster in pdfplumber.utils.cluster_objects(
non_table_words + tables, 'top', tolerance=5):
if 'text' in cluster[0]:
lines.append(' '.join([i['text'] for i in cluster]))
elif 'table' in cluster[0]:
lines.append(cluster[0]['table'])
您可以获取表格的边界框,然后过滤掉其中的所有单词,如下所示:
def check_bboxes(word, table_bbox):
"""
Check whether word is inside a table bbox.
"""
l = word['x0'], word['top'], word['x1'], word['bottom']
r = table_bbox
return l[0] > r[0] and l[1] > r[1] and l[2] < r[2] and l[3] < r[3]
tables = page.find_tables()
table_bboxes = [i.bbox for i in tables]
tables = [{'table': i.extract(), 'doctop': i.bbox[1]} for i in tables]
non_table_words = [word for word in page.extract_words() if not any(
[check_bboxes(word, table_bbox) for table_bbox in table_bboxes])]
lines = []
for cluster in pdfplumber.utils.cluster_objects(non_table_words+tables, 'doctop', tolerance=5):
if 'text' in cluster[0]:
lines.append(' '.join([i['text'] for i in cluster]))
elif 'table' in cluster[0]:
lines.append(cluster[0]['table'])
使用 pdfplumber 库,您可以提取 PDF 页面的文本,也可以从 pdf 页面提取表格。
问题是我似乎找不到提取文本 和 表格的方法。本质上,如果pdf是这样格式化的:
text1
tablename
___________
| Header 1 |
------------
| row 1 |
------------
text 2
我希望输出为:
["text 1",
"table name",
[["header 1"], ["row 1"]],
"text 2"]
在此示例中,您可以 运行 extract_text 来自 pdfplumber:
with pdfplumber.open("example.pdf") as pdf:
for page in pdf.pages:
page.extract_text()
但这会将文本和表格提取为文本。您可以 运行 extract_tables,但这只会给您表格。我需要一种同时提取文本和表格的方法。
这是否以某种我不理解的方式内置到库中?如果不是,这可能吗?
编辑:已回答
这直接来自已接受的答案,并稍作调整以修复它。非常感谢!
def check_bboxes(word, table_bbox):
"""
Check whether word is inside a table bbox.
"""
l = word['x0'], word['top'], word['x1'], word['bottom']
r = table_bbox
return l[0] > r[0] and l[1] > r[1] and l[2] < r[2] and l[3] < r[3]
tables = page.find_tables()
table_bboxes = [i.bbox for i in tables]
tables = [{'table': i.extract(), 'top': i.bbox[1]} for i in tables]
non_table_words = [word for word in page.extract_words() if not any(
[check_bboxes(word, table_bbox) for table_bbox in table_bboxes])]
lines = []
for cluster in pdfplumber.utils.cluster_objects(
non_table_words + tables, 'top', tolerance=5):
if 'text' in cluster[0]:
lines.append(' '.join([i['text'] for i in cluster]))
elif 'table' in cluster[0]:
lines.append(cluster[0]['table'])
您可以获取表格的边界框,然后过滤掉其中的所有单词,如下所示:
def check_bboxes(word, table_bbox):
"""
Check whether word is inside a table bbox.
"""
l = word['x0'], word['top'], word['x1'], word['bottom']
r = table_bbox
return l[0] > r[0] and l[1] > r[1] and l[2] < r[2] and l[3] < r[3]
tables = page.find_tables()
table_bboxes = [i.bbox for i in tables]
tables = [{'table': i.extract(), 'doctop': i.bbox[1]} for i in tables]
non_table_words = [word for word in page.extract_words() if not any(
[check_bboxes(word, table_bbox) for table_bbox in table_bboxes])]
lines = []
for cluster in pdfplumber.utils.cluster_objects(non_table_words+tables, 'doctop', tolerance=5):
if 'text' in cluster[0]:
lines.append(' '.join([i['text'] for i in cluster]))
elif 'table' in cluster[0]:
lines.append(cluster[0]['table'])