Python利用PaddleOCR进行扫描版PDF的跨页表格提取与合并

 更新时间:2025年12月18日 09:01:06   作者:Quest for Knowledge  
在处理PDF文件中的表格时,常常会遇到表格跨页的情况,并且一些PDF文件为扫描版,这种情况下,如果要将跨页的表格合并为一个完整的表格,手动操作不仅繁琐且容易出错,因此,本文将介绍如何利用PaddleOCR和Python代码,自动化地检测并合并这些跨页表格

前言

在处理PDF文件中的表格时,常常会遇到表格跨页的情况。并且一些PDF文件为扫描版。这种情况下,如果要将跨页的表格合并为一个完整的表格,手动操作不仅繁琐且容易出错。因此,本文将介绍如何利用PaddleOCR和Python代码,自动化地检测并合并这些跨页表格。

1.环境准备

首先,我们需要安装以下库:

  • pandas:数据处理
  • paddleocr:OCR识别表格结构
  • pdf2image:将PDF页面转换为图像
  • beautifulsoup4:解析HTML
  • numpy:数组处理

安装命令如下:

pip install pandas paddleocr pdf2image beautifulsoup4 numpy

引入所需的库并设置一些警告和日志配置,以确保代码执行过程中不会被不必要的信息干扰:

import pandas as pd
from paddleocr import PPStructure, save_structure_res
from pdf2image import convert_from_path
from bs4 import BeautifulSoup
import warnings
import numpy as np
import logging
import os

warnings.filterwarnings("ignore")
logging.disable(logging.DEBUG)
logging.disable(logging.WARNING)

2.文件路径与阈值设置

定义PDF文件的路径和一些参数阈值,用于判断表格是否跨页:

path = 'E:/Jobcontent/data/测试/'
output_folder = "E:/table/ex/"
topthreshold = 0.2
dthreshold = 0.8

table_engine = PPStructure(show_log=True)

3.定义辅助函数

这些辅助函数用于提取PDF页面中的表格信息,并判断表格是否跨页。

  • top_bottom_table_info:获取页面中最上方表格的列数和坐标。
  • find_bottom_table_info:获取页面中最下方表格的列数和坐标。
  • is_continuation:判断表格是否跨页。
def top_bottom_table_info(table_result):
    top_table = None
    min_y = 0
    for table in table_result:
        if table['type'] == 'table':
            bbox = table['bbox']
            current_bottom_y = bbox[1]
            if top_table is None or current_bottom_y < min_y:
                top_table = table
                min_y = current_bottom_y

    if top_table is not None:
        soup = BeautifulSoup(top_table['res']['html'], 'html.parser')
        last_row = soup.find_all('tr')[-1]
        columns = last_row.find_all('td')
        top_row_columns = len(columns)
        top_xy = top_table['bbox']
        return top_row_columns, top_xy
    else:
        return None

def find_bottom_table_info(table_result):
    bottom_table = None
    bottom_y = 0
    for table in table_result:
        if table['type'] == 'table':
            bbox = table['bbox']
            current_bottom_y = bbox[3]
            if bottom_table is None or current_bottom_y > bottom_y:
                bottom_table = table
                bottom_y = current_bottom_y

    if bottom_table is not None:
        soup = BeautifulSoup(bottom_table['res']['html'], 'html.parser')
        last_row = soup.find_all('tr')[0]
        columns = last_row.find_all('td')
        last_row_columns = len(columns)
        bottom_xy = bottom_table['bbox']
        return last_row_columns, bottom_xy
    else:
        return None

def is_continuation(top_row_columns, last_row_columns, bottom_xy, top_xy, page_height, dthreshold=0.8, topthreshold=0.2):
    if top_row_columns != last_row_columns:
        return False
    is_last_table_at_bottom = bottom_xy[3] > dthreshold * page_height
    is_first_table_at_top = top_xy[1] < topthreshold * page_height
    return is_last_table_at_bottom and is_first_table_at_top

4.处理PDF文件

读取PDF文件并提取每页的表格信息。对于跨页的表格,提取其列数和坐标,并将结果合并。

  1. 获取PDF文件列表:获取指定路径下所有以“.pdf”结尾的文件。
  2. 逐个处理PDF文件:对于每个PDF文件,初始化一个列表来存储跨页表格信息。
  3. 将PDF页面转换为图像:将PDF文件的每一页转换为图像,并逐页处理。
  4. 提取表格信息:使用table_engine函数从每个页面图像中提取表格信息,并保存结构化结果。
  5. 检测跨页表格:检查当前页的最后一行和下一页的第一行的列数是否相同,如果相同,则记录跨页表格的信息。
  6. 合并跨页表格:对于检测到的跨页表格,读取跨页的两部分表格,合并后保存为CSV文件。
  7. 完成提取:在处理完所有PDF文件后,打印“表格提取完成”的消息。
pdf_files = [f for f in os.listdir(path) if f.endswith('.pdf')]
print(pdf_files)

for pdf_file in pdf_files:
    cross_page_tables = []
    pdf_path = os.path.join(path, pdf_file)
    images = convert_from_path(pdf_path, dpi=200)
    print('正在提取表格,请耐心等待...')
    for page_number, image in enumerate(images):
        table_result = table_engine(np.array(image))
        save_structure_res(table_result, output_folder, f'{page_number+1}')

        _, page_height = image.size
        last_row_columns, bottom_xy = find_bottom_table_info(table_result)
        if page_number+1 < len(images):
            table_result_end = table_engine(np.array(images[page_number+1]))
            top_row_columns, top_xy = top_bottom_table_info(table_result_end)

            if is_continuation(top_row_columns, last_row_columns, bottom_xy, top_xy, page_height):
                cross_page_tables.append((bottom_xy, top_xy, page_number+1, page_number+2))
                print(f"{pdf_file} 的表格在第 {page_number+1} 页和第 {page_number+2} 页之间跨页,并且最后一行和下一页的第一行列数相同")

    if cross_page_tables:
        for (bottom_xy, top_xy, start_page, end_page) in cross_page_tables:
            output_folder_s = output_folder + f'{start_page}/'
            output_folder_t = output_folder + f'{end_page}/'
            file_s = f'{bottom_xy}'+'_0'+'.xlsx'
            file_t = f'{top_xy}'+'_0'+'.xlsx'
            s_path = os.path.join(output_folder_s, file_s)
            e_path = os.path.join(output_folder_t, file_t)
            table_result_start =pd.read_excel(s_path, header=None)
            table_result_end = pd.read_excel(e_path, header=None)
            merged_table = pd.concat([table_result_start, table_result_end], ignore_index=True)
            output_path = os.path.join(output_folder, f'{pdf_file}_merged_{start_page}_{end_page}.csv')
            merged_table.to_csv(output_path, index=False)

print('表格提取完成')

5.总结

通过上述代码,可以实现对扫描版PDF文件中跨页表格的检测与合并,并将结果保存为CSV文件。该方法对提升PDF表格处理的自动化程度和效率具有重要意义。

到此这篇关于Python利用PaddleOCR进行扫描版PDF的跨页表格提取与合并的文章就介绍到这了,更多相关Python PaddleOCR PDF跨页表格提取与合并内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 使用Python操作Excel中的各项页面设置功能

    使用Python操作Excel中的各项页面设置功能

    在使用Excel进行数据分析或报告制作时,页面设置是确保最终输出效果专业、美观的关键步骤,合理的页面设置不仅能够优化打印效果,还能提升数据的可读性,本文将详细介绍如何使用Python操作Excel中的各项页面设置功能,需要的朋友可以参考下
    2024-08-08
  • python中面向对象的注意点概述总结

    python中面向对象的注意点概述总结

    大家好,本篇文章主要讲的是python中面向对象的注意点概述总结,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-02-02
  • python中DataFrame数据合并merge()和concat()方法详解

    python中DataFrame数据合并merge()和concat()方法详解

    Pandas提供了很多合并Series和Dataframe的强大的功能,通过这些功能可以方便的进行数据分析,下面这篇文章主要给大家介绍了关于python中DataFrame数据合并merge()和concat()方法的相关资料,需要的朋友可以参考下
    2022-07-07
  • Python和php通信乱码问题解决方法

    Python和php通信乱码问题解决方法

    Python是在windows下的客户端,用的是cp936编码,php用的是utf-8编码,如果单纯使用urllib.urlencode编码之后post发送的话,php接收过来的中文会是类似\xb0\xe1这种形式的编码
    2014-04-04
  • Pytorch 卷积中的 Input Shape用法

    Pytorch 卷积中的 Input Shape用法

    这篇文章主要介绍了Pytorch 卷积中的 Input Shape用法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-06-06
  • Python实战爬虫之女友欲买文胸不知何色更美

    Python实战爬虫之女友欲买文胸不知何色更美

    实践来源于理论,做爬虫前肯定要先了解相关的规则和原理,网络爬虫又称为网页蜘蛛,网络机器人,更经常的称为网页追逐者,是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。一句话概括就是网上信息搬运工。本篇文章带你深入了解,需要的朋友可以参考下
    2021-09-09
  • Python动态演示旋转矩阵的作用详解

    Python动态演示旋转矩阵的作用详解

    一个矩阵我们想让它通过编程,实现各种花样的变化怎么办呢?下面这篇文章主要给大家介绍了关于Python动态演示旋转矩阵的作用,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2022-12-12
  • Python中几种高效读取大文件的完整指南

    Python中几种高效读取大文件的完整指南

    处理大型文件时,我们需要采用特殊的技术来避免内存溢出,本文主要介绍了Python中几种高效读取大文件的完整指南,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-06-06
  • flask框架配置mysql数据库操作详解

    flask框架配置mysql数据库操作详解

    这篇文章主要介绍了flask框架配置mysql数据库操作,结合实例形式详细分析了flask框架配置mysql数据库及连接访问等相关操作技巧,需要的朋友可以参考下
    2019-11-11
  • Python‘==‘ 及 ‘is‘相关原理解析

    Python‘==‘ 及 ‘is‘相关原理解析

    这篇文章主要介绍了Python‘==‘ 及 ‘is‘相关原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09

最新评论