用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使用urllib2模块获取gravatar头像实例
Dec 18 Python
python时间整形转标准格式的示例分享
Feb 14 Python
详解supervisor使用教程
Nov 21 Python
Python将list中的string批量转化成int/float的方法
Jun 26 Python
关于 Python opencv 使用中的 ValueError: too many values to unpack
Jun 28 Python
python gensim使用word2vec词向量处理中文语料的方法
Jul 05 Python
python os.fork() 循环输出方法
Aug 08 Python
python opencv鼠标事件实现画框圈定目标获取坐标信息
Apr 18 Python
python 表格打印代码实例解析
Oct 12 Python
Python3的socket使用方法详解
Feb 18 Python
使用Pycharm分段执行代码
Apr 15 Python
python 如何区分return和yield
Sep 22 Python
python实现自动化群控的步骤
Apr 11 #Python
python 调用js的四种方式
Apr 11 #Python
Python WSGI 规范简介
使用pytorch实现线性回归
pytorch实现线性回归以及多元回归
python如何获取网络数据
Apr 11 #Python
Pytorch 使用tensor特定条件判断索引
You might like
PHP警告Cannot use a scalar value as an array的解决方法
2012/01/11 PHP
PHP中数组合并的两种方法及区别介绍
2012/09/14 PHP
ThinkPHP CURD方法之field方法详解
2014/06/18 PHP
PHP+APACHE实现网址伪静态
2015/02/22 PHP
PHP数据库连接mysql与mysqli对比分析
2016/01/04 PHP
PHP闭包函数传参及使用外部变量的方法
2016/03/15 PHP
php使用Jpgraph创建柱状图展示年度收支表效果示例
2017/02/15 PHP
javascript笔试题目附答案@20081025_jb51.net
2008/10/26 Javascript
网页源代码保护(禁止右键、复制、另存为、查看源文件)
2012/05/23 Javascript
JavaScript 变量、作用域及内存
2015/04/08 Javascript
详解maxlength属性在textarea里奇怪的表现
2015/12/27 Javascript
WEB前端实现裁剪上传图片功能
2016/10/17 Javascript
原生js实现网页顶部自动下拉/收缩广告效果
2017/01/20 Javascript
Angular2使用Augury来调试Angular2程序
2017/05/21 Javascript
基于layer.js实现收货地址弹框选择然后返回相应的地址信息
2017/05/26 Javascript
详解Angular 自定义结构指令
2017/06/21 Javascript
使用vue-router beforEach实现判断用户登录跳转路由筛选功能
2018/06/25 Javascript
微信小程序 下拉刷新及上拉加载原理解析
2019/11/06 Javascript
[04:54]DOTA2 2017国际邀请赛:上届冠军WINGS采访短片
2017/08/09 DOTA
python单线程实现多个定时器示例
2014/03/30 Python
Pyhthon中使用compileall模块编译源文件为pyc文件
2015/04/28 Python
浅谈Python类里的__init__方法函数,Python类的构造函数
2016/12/10 Python
Python读取指定目录下指定后缀文件并保存为docx
2017/04/23 Python
对numpy中数组元素的统一赋值实例
2018/04/04 Python
python 字典修改键(key)的几种方法
2018/08/10 Python
Speedo速比涛法国官方网站:泳衣、泳镜、泳帽、泳裤
2019/07/30 全球购物
adidas菲律宾官网:adidas PH
2020/02/07 全球购物
出国留学经济担保书
2014/04/01 职场文书
五月的鲜花活动方案
2014/08/21 职场文书
司法局群众路线教育实践活动整改措施
2014/09/17 职场文书
在职证明书范本(2014新版)
2014/09/25 职场文书
党员公开承诺书2015
2015/01/21 职场文书
给女朋友的道歉短信
2015/05/12 职场文书
大学生受助感言
2015/08/01 职场文书
执行力心得体会范文
2016/01/11 职场文书
口袋妖怪冰系十大最强精灵,几何雪花排第七,第六类似北极熊
2022/03/18 日漫