用Python提取PDF表格的方法


Posted in Python onApril 11, 2021

大家好,从PDF中提取信息是办公场景中经常需要用到的操作,也是经常又读者在后台问的一个操作。

内容少的话我们可以手动复制粘贴,但如果需要批量提取就可以考虑使用Python,之前我也转载过相关文章,提到主要就是使用pdfplumber库,今天我们再次举例讲解。

通常PDF里的表格分为图片型和文本型。文本型又分简单型和复杂型。本文就针对这三部分举例讲解。

  • 提取简单型表格
  • 提取较为复杂型表格
  • 提取图片型表格

用Python提取PDF表格的方法

用到的模块主要有

  • pdfplumber
  • pandas
  • Tesseract
  • PIL

文中出现的PDF材料是在巨潮资讯官网下载的公开PDF文件,主题是关于理财的,相关发布信息等信息如下:

用Python提取PDF表格的方法

内容总共有6页,后文中的例子会有展示。

一、简单文本类型数据

简单文本类型表格就是一页PDF中只有一个表格,并且表格内容完整可复制,例如我们选定内容为PDF中的第四页,内容如下:

用Python提取PDF表格的方法

可以看到,该页只有一个表格,下面我们将这个表写入Excel中,先上代码

import pdfplumber as pr
import pandas as pd
pdf = pr.open('关于使用自有资金购买银行理财产品的进展公告.PDF')
ps = pdf.pages
pg = ps[3]
tables = pg.extract_tables()
table = tables[0]
print(table)
df = pd.DataFrame(table[1:],columns = table[0])
for i in range(len(table)):
    for j in range(len(table[i])):
        table[i][j] = table[i][j].replace('\n','')
df1 = pd.DataFrame(table[1:],columns = table[0])
df1.to_excel('page2.xlsx')

得到的结果如下:

用Python提取PDF表格的方法

通过与PDF上原表格对比,在内容上是完全一致的,唯一不同的是由于主营业务内容较多,导致显示的不全面,现在来说说这段代码。

首先导入要用到的两个库。在pdfplumber中,open()函数是用来打开PDF文件,该代码用的是相对路径。.open().pages则是获取PDF的页数,打印ps值可以得到如下

用Python提取PDF表格的方法

pg = ps[3]代表的就是我们所选的第三页。

pg.extract_tables():可输出页面中所有表格,并返回一个嵌套列表,其结构层次为table→row→cell。此时,页面上的整个表格被放入一个大列表中,原表格中的各行组成该大列表中的各个子列表。若需输出单个外层列表元素,得到的便是由原表格同一行元素构成的列表。

与其类似的是pg.extract_table( ):返回多个独立列表,其结构层次为row→cell。若页面中存在多个行数相同的表格,则默认输出顶部表格;否则,仅输出行数最多的一个表格。此时,表格的每一行都作为一个单独的列表,列表中每个元素即为原表格的各个单元格内容。

由于该页面中只有一个表格,我们需要tables集合中的第一个元素。打印table值,如下:

用Python提取PDF表格的方法

可以看到在上述中是存在\n这种没不要的字符,它的作用其实是换行但我们在Excel中是不需要的。所以需要剔除它,用代码中的for循环与replace函数将控制替换成空格(即删除\n)。观察table是一个装有2个元素的列表。

最后df1 = pd.DataFrame(table[1:],columns = table[0])这段代码的作用就是创建一个数据框,将内容放到对应的行列中。

本代码只是简单将数据存入到Excel,如果你需要进一步对样式进行调整,可以使用openpyxl等模块进行修改。

二、复杂型表格提取

复杂型表格即表格样式不统一或一页中有多个表格,以PDF中的第五页为例:

用Python提取PDF表格的方法

可以看到本页中有两个大的表格,并且细看的话,其实是4个表格,按照简单型表格类型提取方法,得到的效果如下:

用Python提取PDF表格的方法

可以看到,只是将全部表格文本提取出来,但实际上第一个表格又细分为两个表,所以需要我们进一步修改,将这张表再次拆分!例如提取上半部分代码如下:

import pdfplumber as pr
import pandas as pd
pdf = pr.open('关于使用自有资金购买银行理财产品的进展公告.PDF')
ps = pdf.pages
pg = ps[4]
tables = pg.extract_tables()
table = tables[0]
print(table)
df = pd.DataFrame(table[1:],columns = table[0])
for i in range(len(table)):
    for j in range(len(table[i])):
        table[i][j] = table[i][j].replace('\n','')
df1 = pd.DataFrame(table[1:],columns = table[0])
df2 = df1.iloc[2:,:]
df2 = df2.rename(columns = {"2019年12月31日":"2019年1-12月","2020年9月30日":"2020年1-9月"})
df2 = df2.loc[3:,:]
df1 = df1.loc[:1,:]
with pd.ExcelWriter('公司影响.xlsx') as i:
    df1.to_excel(i,sheet_name='资产', index=False, header=True) #放入资产数据
    df2.to_excel(i,sheet_name='营业',index=False, header=True) #放入营业数据

这段代码在简单型表格提取的基础上进行了修改,第十四行代码的作用就是提取另外一个表头的信息,并将他赋值给df2,而后对df2进行重命名操作(用到rename函数)。

打印df2可以看出columns列名和第一行信息重复了,因此我们需要重复刚刚的步骤,利用loc()函数切割数据框。

注意,我们这里用了罕见的pandas.Excelwriter函数套for循环,这个是为了避免直接写入导致的最后数据覆盖原数据,感兴趣可以尝试一下不用withopen这种方法后结果。最终得到的效果如下:

用Python提取PDF表格的方法

用Python提取PDF表格的方法

可以看到,现在这个表格就被放在两个sheet中单独展示,当然用于对比放在一张表中也是可以的

用Python提取PDF表格的方法

说到底复杂型表格的主观性是非常大的,需要根据不同情况进行不同处理,想写出一个一劳永逸的办法是比较困难的!

三、图片型表格提取

最后也是最难处理的就是图片型表格,经常有人会问如何提取图片型PDF中的表格/文本等信息。

其实本质上就是提取图片,之后如何对图片进一步处理提取信息就与Python提取PDF表格这个主题没有太大关系了!

这里我们也简单进行介绍,也就是先提取图片再进行OCR识别提取表格,在Python中可以使用Tesseract库,首先需要pip安装

pip install pytesseract

在Python中安装完这个库之后我们需要安装exe文件以在后面代码用到。

http://digi.bib.uni-mannheim.de/tesseract/tesseract-ocr-setup-4.00.00dev.exe

下载安装完即可,注意目前如果按照正常步骤安装的话是不会识别中文的,所以需要安装简体中文语言包,下载地址为https://github.com/tesseract-ocr/tessdata/find/master/chi_sim.traineddata,将其放到Tesseract-OCR的tessdata目录下即可。

接下来我们使用一个简单的图片型pdf如下:

用Python提取PDF表格的方法

第一步,提取图片,这里使用在GUI办公自动化系列中的图片提取软件来提取PDF中的图片,得到如下图片:

用Python提取PDF表格的方法

接着执行下方代码识别图片内容

import pytesseract
from PIL import Image
import pandas as pd
pytesseract.pytesseract.tesseract_cmd = 'C://Program Files (x86)/Tesseract-OCR/tesseract.exe'
tiqu = pytesseract.image_to_string(Image.open('图片型.jpg'))
print(tiqu)
tiqu = tiqu.split('\n')
while '' in tiqu:    #不能使用for
  tiqu.remove('')
  first = tiqu[:6]
  second = tiqu[6:12]
  third =  tiqu[12:]
  df = pd.DataFrame()
  df[first[0]] = first[1:]
  df[second[0]] = second[1:]
  df[third[0]] = third[1:]
#df.to_excel('图片型表格.xlsx')  #转为xlsx文件

我们的思路是用Tesseract-OCR来解析图片,得到一个字符串,接着对字符串运用split函数,把字符串变成列表同时删除\n。

接着可以发现我们的列表里还存在空格,这时我们用while循环来删除这些空字符,注意,这里不能用for循环,因为每次删除一个,列表里的元素就会前进一个,这样会删不完全。最后就是用pandas把这些变成数据框形式。最终得到的效果如下:

用Python提取PDF表格的方法

可以看到,该图片型表格内容被完美解析与处理!当然能轻松搞定的原因也与这个表格足够简单有关,在真实场景中的图片可能会有更复杂的干扰因素,而这就需要大家在处理的同时自行找到一个最合适的办法!

以上就是用Python提取PDF表格的方法的详细内容,更多关于Python提取PDF表格的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
Python将字符串常量转化为变量方法总结
Mar 17 Python
pip 安装库比较慢的解决方法(国内镜像)
Oct 06 Python
详解python路径拼接os.path.join()函数的用法
Oct 09 Python
Python如何计算语句执行时间
Nov 22 Python
python getopt模块使用实例解析
Dec 18 Python
pytorch方法测试——激活函数(ReLU)详解
Jan 15 Python
python判断两个序列的成员是否一样的实例代码
Mar 01 Python
python实现逢七拍腿小游戏的思路详解
May 26 Python
PyQt5的QWebEngineView使用示例
Oct 20 Python
Python爬虫之Selenium实现键盘事件
Dec 04 Python
python中子类与父类的关系基础知识点
Feb 02 Python
python利用xpath爬取网上数据并存储到django模型中
Feb 26 Python
python实现自动化群控的步骤
Apr 11 #Python
python 调用js的四种方式
Apr 11 #Python
Python WSGI 规范简介
使用pytorch实现线性回归
pytorch实现线性回归以及多元回归
python如何获取网络数据
Apr 11 #Python
Pytorch 使用tensor特定条件判断索引
You might like
PHP redis实现超迷你全文检索
2017/03/04 PHP
xml 与javascript结合的问题解决方法
2007/03/24 Javascript
jquery中防刷IP流量软件影响统计的一点对策
2011/07/10 Javascript
Javascript模块化编程(三)require.js的用法及功能介绍
2013/01/17 Javascript
js css后面所带参数含义介绍
2013/08/18 Javascript
JavaScript及jquey实现多个数组的合并操作
2014/09/06 Javascript
做web开发 先学JavaScript
2014/12/12 Javascript
浅谈重写window对象的方法
2014/12/29 Javascript
js由下向上不断上升冒气泡效果实例
2015/05/07 Javascript
js实现延迟加载的方法
2015/06/24 Javascript
NodeJS连接MongoDB数据库时报错的快速解决方法
2016/05/13 NodeJs
JS表格组件BootstrapTable行内编辑解决方案x-editable
2016/09/01 Javascript
vue2.0实战之使用vue-cli搭建项目(2)
2017/03/27 Javascript
vue2.0结合Element实现select动态控制input禁用实例
2017/05/12 Javascript
浅谈Express异步进化史
2017/09/09 Javascript
JavaScript笛卡尔积超简单实现算法示例
2018/07/30 Javascript
微信小程序提取公用函数到util.js及使用方法示例
2019/01/10 Javascript
vue路由分文件拆分管理详解
2020/08/13 Javascript
原生js实现照片墙效果
2020/10/13 Javascript
Python搭建HTTP服务器和FTP服务器
2017/03/09 Python
python制作小说爬虫实录
2017/08/14 Python
python 实现对文件夹中的图像连续重命名方法
2018/10/25 Python
Python后台管理员管理前台会员信息的讲解
2019/01/28 Python
Python利用scapy实现ARP欺骗的方法
2019/07/23 Python
CSS3实现的炫酷菜单代码分享
2015/03/12 HTML / CSS
html5的input的required使用中遇到的问题及解决方法
2018/04/24 HTML / CSS
Melissa鞋英国官方网站:Nonnon
2019/05/01 全球购物
在数据文件自动增长时,自动增长是否会阻塞对文件的更新
2014/05/01 面试题
营销专业应届生求职信
2013/11/26 职场文书
校本教研工作制度
2014/01/22 职场文书
冰淇淋开店创业计划书
2014/02/01 职场文书
三年级评语大全
2014/04/23 职场文书
中学生自我评价范文
2015/03/03 职场文书
[有人@你]你有一封绿色倡议书,请查收!
2019/07/18 职场文书
《围炉夜话》110句人生箴言,精辟有内涵,引人深思
2019/10/23 职场文书
php字符串倒叙
2021/04/01 PHP