pdf 是个异常坑爹的东西,有很多处理 pdf 的库,但是没有完美的。

一、pdfminer3k

pdfminer3k 是 pdfminer 的 python3 版本,主要用于读取 pdf 中的文本。

网上有很多 pdfminer3k 的代码示例,看过以后,只想吐槽一下,太复杂了,有违 python 的简洁。

from pdfminer.pdfparser importPDFParser, PDFDocumentfrom pdfminer.pdfinterp importPDFResourceManager, PDFPageInterpreterfrom pdfminer.converter importPDFPageAggregatorfrom pdfminer.layout importLAParams, LTTextBoxfrom pdfminer.pdfinterp importPDFTextExtractionNotAllowed

path= "test.pdf"

#用文件对象来创建一个pdf文档分析器

praser = PDFParser(open(path, 'rb'))#创建一个PDF文档

doc =PDFDocument()#连接分析器 与文档对象

praser.set_document(doc)

doc.set_parser(praser)#提供初始化密码#如果没有密码 就创建一个空的字符串

doc.initialize()#检测文档是否提供txt转换,不提供就忽略

if notdoc.is_extractable:raisePDFTextExtractionNotAllowedelse:#创建PDf 资源管理器 来管理共享资源

rsrcmgr =PDFResourceManager()#创建一个PDF设备对象

laparams =LAParams()

device= PDFPageAggregator(rsrcmgr, laparams=laparams)#创建一个PDF解释器对象

interpreter =PDFPageInterpreter(rsrcmgr, device)#循环遍历列表,每次处理一个page的内容

for page indoc.get_pages():

interpreter.process_page(page)#接受该页面的LTPage对象

layout =device.get_result()#这里layout是一个LTPage对象,里面存放着这个 page 解析出的各种对象

#包括 LTTextBox, LTFigure, LTImage, LTTextBoxHorizontal 等

for x inlayout:ifisinstance(x, LTTextBox):print(x.get_text().strip())

pdfminer 对于表格的处理非常的不友好,能提取出文字,但是没有格式:

pdf表格截图:

代码运行结果:

想把这个结果还原成表格可不容易,加的规则太多必然导致通用性的下降。

二、tabula-py

tabula 是专门用来提取PDF表格数据的,同时支持PDF导出为CSV、Excel格式,但是这工具是用 java 写的,依赖 java7/8。tabula-py 就是对它做了一层 python 的封装,所以也依赖 java7/8。

代码很简单:

importtabula

path= 'test.pdf'df= tabula.read_pdf(path, encoding='gbk', pages='all')for indexs indf.index:print(df.loc[indexs].values)#tabula.convert_into(path, os.path.splitext(path)[0]+'.csv', pages='all')

虽然号称是专业处理 pdf 中的表格的,但实际效果也不咋地。还是 pdfminer 中使用的 pdf,运行结果如下:

这结果真的很尴尬啊,表头识别就错了,还有 pdf 中有两张表,我没发现怎么区分表。

三、pdfplumber

pdfplumber 是按页来处理 pdf 的,可以获得页面的所有文字,并且提供的单独的方法用于提取表格。

importpdfplumber

path= 'test.pdf'pdf=pdfplumber.open(path)for page inpdf.pages:#获取当前页面的全部文本信息,包括表格中的文字

#print(page.extract_text())

for table inpage.extract_tables():#print(table)

for row intable:print(row)print('---------- 分割线 ----------')

pdf.close()

得到的 table 是个 string 类型的二维数组,这里为了跟 tabula 比较,按行输出显示。

可以看到,跟 tabula 相比,首先是可以区分表格,其次,准确率也提高了很多,表头的识别完全正确。对于表格中有换行的,识别还不是很正确,但至少列的划分没问题,所以还是能处理的。

importpdfplumberimportre

path= 'test1.pdf'pdf=pdfplumber.open(path)for page inpdf.pages:print(page.extract_text())for pdf_table inpage.extract_tables():

table=[]

cells=[]for row inpdf_table:if notany(row):#如果一行全为空,则视为一条记录结束

ifany(cells):

table.append(cells)

cells=[]elifall(row):#如果一行全不为空,则本条为新行,上一条结束

ifany(cells):

table.append(cells)

cells=[]

table.append(row)else:if len(cells) ==0:

cells=rowelse:for i inrange(len(row)):if row[i] is notNone:

cells[i]= row[i] if cells[i] is None else cells[i] +row[i]for row intable:print([re.sub('\s+', '', cell) if cell is not None else None for cell inrow])print('---------- 分割线 ----------')

pdf.close()

经过处理后,运行得到结果:

这结果已经完全正确了,而用 tabula,即便是经过处理也是无法得到这样的结果的。当然对于不同的 pdf,可能需要不同的处理,实际情况还是要自己分析。

pdfplumber 也有处理不准确的时候,主要表现在缺列:

我找了另一个 pdf,表格部分截图如下:

解析结果如下:

4列变成了两列,另外,如果表格有合并单元格的情况,也会有这种问题,我挑这个表格展示是因为比较特殊,没有合并单元格也缺列了。这应该跟 pdf 生成的时候有关。

但其实数据是获取完整的,并没有丢,只是被认为是非表格了。输出 page.extract_text() 如下:

然后,我又用 tabula 试了下,结果如下:

列是齐了,但是,表头呢???

pdfplumber 还提供了图形Debug功能,可以获得PDF页面的截图,并且用方框框起识别到的文字或表格,帮助判断PDF的识别情况,并且进行配置的调整。要使用这个功能,还需要安装ImageMagick。因为没有用到,所以暂时没有去细究。

四、后记

我们在做爬虫的时候,难免会遇到 pdf 需要解析,主要还是针对文本和表格的数据提取。而 python 处理 pdf 的库实在是太多太多了,比如还有 pypdf2,网上资料也比较多,但是我试了,读出来是乱码,没有仔细的读源码所以这个问题也没有解决。

而我对比较常用的3个库比较后觉得,还是 pdfplumber 比较好用,对表格的支持最好。

相关博文推荐:

python读取pdf表格_【Python 库】解析PDF文本及表格——pdfminer、tabula、pdfplumber 的用法及对比...相关推荐

  1. python读取图片属性_[Python图像处理]三.获取图像属性及通道处理

    获取图像属性 1: 形状-shape: 通过shape关键字获取图像的形状,返回包含行数.列数.通道数的元祖.其中灰度图像返回行数和列数,彩色图像返回行数.列数和通道数 importcv2 img= ...

  2. 【python脚本系列】利用mido库解析midi文件

    [python脚本系列]利用mido库解析midi文件       Hallo大家好~~我是Lampard猿奋       昨天写了关于Midi数字化乐器接口的文章,介绍了midi是一组代表音乐参数( ...

  3. python读取matlab数据_详解如何在python中读写和存储matlab的数据文件(*.mat)

    背景 在做deeplearning过程中,使用caffe的框架,一般使用matlab来处理图片(matlab处理图片相对简单,高效),用python来生成需要的lmdb文件以及做test产生结果.所以 ...

  4. Python:解析PDF文本及表格——pdfminer、tabula、pdfplumber 的用法及对比

    pdf 是个异常坑爹的东西,有很多处理 pdf 的库,但是没有完美的. 一.pdfminer3k pdfminer3k 是 pdfminer 的 python3 版本,主要用于读取 pdf 中的文本. ...

  5. python自动化pdf报告_[Python] 自动化办公 PDF提取文字、表格、图片

    转载请注明:陈熹 chenx6542@foxmail.com (简书号:半为花间酒) 若公众号内转载请联系公众号:早起Python 本例可以学到的知识点: 使用 pdfplumber 提取 PDF 中 ...

  6. python求excel平均数_#python抓取excel表格数据#使用python3读取处理excel表的数据内容如何对内容求平均值...

    使用python3读取处理excel表的数据内容如何对内容求平均值 先说下概述: 值就是集合平均数. (a1 a2 --an)/n为a1,a2,--,an术平均值. 简单算均数.有这么一组数字10.2 ...

  7. Python 中 xpath 语法 与 lxml 库解析 HTML/XML 和 CSS Selector

    The lxml.etree Tutorial :https://lxml.de/tutorial.html python3 解析 xml:https://www.cnblogs.com/deadwo ...

  8. python读取第二行_使用Python操作Excel(二):读取数据表

    上一节我们提到,使用openpyxl可以方便的对数据表进行操作,例如:抽象Excel数据并存入数据库 将数据库数据导出到Excel 给一个已存在的数据表追加信息 我们还介绍了一些Excel的基本术语, ...

  9. python环境变量配置_?Python项目读取配置的正确姿势

    读取配置是大部分python应用都会面临的问题,例如应用运行时需要读取数据库的配置,存储文件需要知道文件路径配置,应用在不同的环境的配置也不尽相同.因此,配置管理是一个必不可少的问题,配置读取的方式一 ...

最新文章

  1. 寻找两个字符串相似度的代码
  2. /proc/kcore失效,调试其文件系统相关模块,使重新正常工作
  3. 如何使用gnvm自动更新Windows10操作系统上的nodejs
  4. 网络编程-Socket介绍
  5. 在spring官网上下载历史版本的spring插件,springsource-tool-suite
  6. Emscripten 单词_人教版英语八年级上册听力(单词+课文) 朗读录音听力mp3音频电子课本(完整版)...
  7. 《网络协议从入门到底层原理》学习笔记
  8. openCV中sobel边缘增强
  9. 劈荆斩棘:Gitlab 部署 CI 持续集成
  10. Python爬虫与信息提取(五)爬虫实例:爬取新浪微博热搜排名
  11. html手机响应式布局,手机网页设计中的响应式布局
  12. 怎么添加扫描仪到计算机快捷键,Win7系统扫描仪添加方法
  13. 通过矩形的中心坐标与原顶点坐标以及旋转角度计算矩形的旋转后4个顶点的位置...
  14. 随机产生10个整数;设计一个算法找其中的最大的元素和最小的元素,并统计元素之间的比较次数
  15. 小米4 第三方re奇兔_【PC】小米运动刷步数 微信 QQ 支付宝 蚂蚁森林每天296g能量...
  16. 技术里的故事里的技术
  17. 迪克斯特拉算法——算法图解
  18. html添加蒙层,html蒙层弹窗
  19. 电子工程师必会的18大技能
  20. Android-Camera内存问题剖析,小白也能看明白

热门文章

  1. 2.分布式文件系统HDFS之一
  2. 14.文件系统:高大上的东西——import关键字/模块
  3. 【c++】4.std::shared_ptr、std::make_shared、 .get() 、.data()、void *p 的用法、裸指针
  4. 微博收藏(机器学习课程与论文)(三)
  5. 面试必备:LinkedHashMap源码解析(JDK8)
  6. 梯度下降(Gradient Descent),一句代码,一个式子
  7. 《精通Hadoop》:第 1 章 Hadoop 2.X
  8. Stanford UFLDL教程 用反向传导思想求导
  9. 线性代数的学习及相关资源
  10. HDU2553 N皇后问题