Python:解析PDF文本及表格——pdfminer、tabula、pdfplumber 的用法及对比
pdf 是个异常坑爹的东西,有很多处理 pdf 的库,但是没有完美的。
一、pdfminer3k
pdfminer3k 是 pdfminer 的 python3 版本,主要用于读取 pdf 中的文本。
网上有很多 pdfminer3k 的代码示例,看过以后,只想吐槽一下,太复杂了,有违 python 的简洁。
from pdfminer.pdfparser import PDFParser, PDFDocument
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import PDFPageAggregator
from pdfminer.layout import LAParams, LTTextBox
from pdfminer.pdfinterp import PDFTextExtractionNotAllowed path = "test.pdf" # 用文件对象来创建一个pdf文档分析器
praser = PDFParser(open(path, 'rb'))
# 创建一个PDF文档
doc = PDFDocument()
# 连接分析器 与文档对象
praser.set_document(doc)
doc.set_parser(praser) # 提供初始化密码
# 如果没有密码 就创建一个空的字符串
doc.initialize() # 检测文档是否提供txt转换,不提供就忽略
if not doc.is_extractable:
raise PDFTextExtractionNotAllowed
else:
# 创建PDf 资源管理器 来管理共享资源
rsrcmgr = PDFResourceManager()
# 创建一个PDF设备对象
laparams = LAParams()
device = PDFPageAggregator(rsrcmgr, laparams=laparams)
# 创建一个PDF解释器对象
interpreter = PDFPageInterpreter(rsrcmgr, device) # 循环遍历列表,每次处理一个page的内容
for page in doc.get_pages():
interpreter.process_page(page)
# 接受该页面的LTPage对象
layout = device.get_result()
# 这里layout是一个LTPage对象,里面存放着这个 page 解析出的各种对象
# 包括 LTTextBox, LTFigure, LTImage, LTTextBoxHorizontal 等
for x in layout:
if isinstance(x, LTTextBox):
print(x.get_text().strip())
pdfminer 对于表格的处理非常的不友好,能提取出文字,但是没有格式:
pdf表格截图:

代码运行结果:

想把这个结果还原成表格可不容易,加的规则太多必然导致通用性的下降。
二、tabula-py
tabula 是专门用来提取PDF表格数据的,同时支持PDF导出为CSV、Excel格式,但是这工具是用 java 写的,依赖 java7/8。tabula-py 就是对它做了一层 python 的封装,所以也依赖 java7/8。
代码很简单:
import tabula path = 'test.pdf' df = tabula.read_pdf(path, encoding='gbk', pages='all')
for indexs in df.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 的,可以获得页面的所有文字,并且提供的单独的方法用于提取表格。
import pdfplumber path = 'test.pdf'
pdf = pdfplumber.open(path) for page in pdf.pages:
# 获取当前页面的全部文本信息,包括表格中的文字
# print(page.extract_text()) for table in page.extract_tables():
# print(table)
for row in table:
print(row)
print('---------- 分割线 ----------') pdf.close()
得到的 table 是个 string 类型的二维数组,这里为了跟 tabula 比较,按行输出显示。

可以看到,跟 tabula 相比,首先是可以区分表格,其次,准确率也提高了很多,表头的识别完全正确。对于表格中有换行的,识别还不是很正确,但至少列的划分没问题,所以还是能处理的。
import pdfplumber
import re path = 'test1.pdf'
pdf = pdfplumber.open(path) for page in pdf.pages:
print(page.extract_text())
for pdf_table in page.extract_tables():
table = []
cells = []
for row in pdf_table:
if not any(row):
# 如果一行全为空,则视为一条记录结束
if any(cells):
table.append(cells)
cells = []
elif all(row):
# 如果一行全不为空,则本条为新行,上一条结束
if any(cells):
table.append(cells)
cells = []
table.append(row)
else:
if len(cells) == 0:
cells = row
else:
for i in range(len(row)):
if row[i] is not None:
cells[i] = row[i] if cells[i] is None else cells[i] + row[i]
for row in table:
print([re.sub('\s+', '', cell) if cell is not None else None for cell in row])
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:读取 .doc、.docx 两种 Word 文件简述及“Word 未能引发事件”错误
Python:解析PDF文本及表格——pdfminer、tabula、pdfplumber 的用法及对比的更多相关文章
- 用python解析pdf中的文本与表格【pdfplumber的安装与使用】
我们接触到的很多文档资料都是以pdf格式存在的,比如:论文,技术文档,标准文件,书籍等.pdf格式使得用机器从中提取信息格外困难. 为了解决这个问题,我找到了几种解决方案,最后选择了python上的p ...
- Python解析PDF三法
span{line-height:2em} --> 最近做调研想知道一些NZ当地的旅游信息,于是在NZ留学的友人自高奋勇地帮我去各个加油站拿了一堆旅游小册子,扫描了发给我. 但是他扫描出的高清图 ...
- 深入学习Python解析并解密PDF文件内容的方法
前面学习了解析PDF文档,并写入文档的知识,那篇文章的名字为深入学习Python解析并读取PDF文件内容的方法. 链接如下:https://www.cnblogs.com/wj-1314/p/9429 ...
- 深入学习python解析并读取PDF文件内容的方法
这篇文章主要学习了python解析并读取PDF文件内容的方法,包括对学习库的应用,python2.7和python3.6中python解析PDF文件内容库的更新,包括对pdfminer库的详细解释和应 ...
- Python3.x:PDFMiner3k在线、本地解析pdf
Python3.x:PDFMiner3k在线.本地解析pdf 安装 pip install pdfminer3k 示例一:在线解析pdf ''' Demo:pdf2htmlex解析pdf Dateti ...
- python3使用pdfminer3k解析pdf文件
安装pdfminer模块 pip3 install pdfminer3k 代码如下 #!/usr/bin/env python # coding:utf8 # author:Z time:2018/7 ...
- python read PDF for chinese
import sys import importlib importlib.reload(sys) from pdfminer.pdfparser import PDFParser,PDFDocume ...
- LIMS系统仪器数据采集-使用xpdf解析pdf内容
不同语言解析PDF内容都有各自的库,比如Java的pdfbox,.net的itextsharp. c#解析PDF文本,关键代码可参考: http://www.cnblogs.com/mahongbia ...
- C#仪器数据文件解析-PDF文件
不少仪器工作站输出的数据报告文件为PDF格式,PDF格式用于排版打印,但不易于数据解析,因此解析PDF数据需要首先读取到PDF文件中的文本内容,然后根据内容规则解析有意义的数据信息. C#解析PDF文 ...
随机推荐
- 【NOIP模拟赛】随
题目链接: 172.18.111.252:800/problem.php?cid=1001&pid=0 题解: 膜达神……(NOIP考这个就等爆零吧……) 显然我们得到一个结论:$ans=\s ...
- java JDK配置环境变量
1)将下载的jdk放置到一定文件夹中,注意文件夹名不能有中文! 2)设置环境变量 a.可以在系统变量中找到path这个变量,然后将jdk下的bin的根目录添加进去 注意:一定要放在path变量值的最前 ...
- 轻量化卷积神经网络MobileNet论文详解(V1&V2)
本文是 Google 团队在 MobileNet 基础上提出的 MobileNetV2,其同样是一个轻量化卷积神经网络.目标主要是在提升现有算法的精度的同时也提升速度,以便加速深度网络在移动端的应用.
- koa+mysql+vue+socket.io全栈开发之前端篇
React 与 Vue 之间的对比,是前端的一大热门话题. vue 简易上手的脚手架,以及官方提供必备的基础组件,比如 vuex,vue-router,对新手真的比较友好:react 则把这些都交给社 ...
- 前端笔记之Vue(一)初识SPA和Vue&webpack配置和vue安装&指令
一.单页面应用(SPA) 1.1 C/S到B/S页面架构的转变 C/S:客户端/服务器(Client/Server)架构的软件. C/S 软件的特点: ① 从window桌面双击打开 ② 更新的时候会 ...
- 用Python学分析 - t分布
1. t分布形状类似于标准正态分布2. t分布是对称分布,较正态分布离散度强,密度曲线较标准正态分布密度曲线更扁平3. 对于大型样本,t-值与z-值之间的差别很小 作用- t分布纠正了未知的真实标 ...
- 《HelloGitHub》第 36 期
公告 本期内容较多.本期共有 41 个项目:C# 项目(1),C++ 项目(1),CSS 项目(2),Go 项目(5),Java 项目(2),JavaScript 项目(5),Objective-C ...
- Python爬虫入门教程 38-100 教育部高校名单数据爬虫 scrapy
爬前叨叨 今天要爬取一下正规大学名单,这些名单是教育部公布具有招生资格的高校名单,除了这些学校以外,其他招生的单位,其所招学生的学籍.发放的毕业证书国家均不予承认,也就是俗称的野鸡大学! 网址是 ht ...
- Unity_新手必懂知识点
翻车了!!!一个小例子带你了解闭包.事故现场:场景:6个button,上方1个text.点击button,text会显示button上的数字.代码如下: //在unity里面赋值public List ...
- 搭建基于SornaQube的自动化安全代码检测平台
一.背景和目的 近年来,随着新业务.新技术的快速发展,应用软件安全缺陷层出不穷.虽然一般情况下,开发者基本都会有单元测试.每日构建.功能测试等环节来保证应用的可用性.但在安全缺陷方面,缺乏安全意识.技 ...