深入学习python解析并读取PDF文件内容的方法

时间:2021-09-25 03:36:48

  这篇文章主要学习了python解析并读取PDF文件内容的方法,包括对学习库的应用,python2.7和python3.6中python解析PDF文件内容库的更新,包括对pdfminer库的详细解释和应用。主要参考了一些已有的博客内容,代码。

  主要思路是首先利用一个做项目的形式,描述所做的问题,运行环境,和需要安装的库,然后写代码,此代码是在python2.7中运行,小编也写出在python3.6中运行的代码,并详细解释python2.7和python3.6中python库的一些不同之处,最后详细的解释了代码的意思,和库的思路,最终的目的就让我们理解,并学会应用python解析并读取PDF文件内容的方法。

一,问题描述

  利用python读取PDF文本内容

二,运行环境

  python 3.6

三, 需要安装的库

pip install pdfminer

  对pdfminer的简单介绍,官网介绍如下:

  PDFMiner is a tool for extracting information from PDF documents. Unlike other PDF-related tools, it focuses entirely on getting and analyzing text data. PDFMiner allows to obtain the exact location of texts in a page, as well as other information such as fonts or lines. It includes a PDF converter that can transform PDF files into other text formats (such as HTML). It has an extensible PDF parser that can be used for other purposes instead of text analysis.

翻译是这样的:

PDFMiner是一个从PDF文档中提取信息的工具。与其他pdf相关的
工具不同,它完全专注于获取和分析文本数据。PDFMiner允许获取
页面中文本的确切位置,以及其他信息,比如字体或行。它包括一
个PDF转换器,可以将PDF文件转换成其他文本格式(如HTML)。
它有一个可扩展的PDF解析器,可以用于其他目的而不是文本分析。

  

四,实现源代码(其中代码1和代码2都是python2.7实现的)

python2中相关库的安装

  python各种库下载地址:

https://www.lfd.uci.edu/~gohlke/pythonlibs/

https://pypi.python.org/pypi/

找到pdfminer,下载,然后上传到服务器上,直接安装即可。

  但是由于Python2和python3版本之间的不兼容,所以对应不同的版本,我们这里需要使用不同的特定环境。

    其中的Pdfminer版本是pdfminer 20140328(对于python2.x的测试没有任何问题)

#_*_coding:utf-8_*_

from pdfminer.pdfparser import  PDFParser
from pdfminer.pdfdocument import PDFDocument
from pdfminer.pdfpage import PDFPage
from pdfminer.pdfdevice import PDFDevice
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import PDFPageAggregator
from pdfminer.layout import LTTextBoxHorizontal,LAParams
from pdfminer.pdfpage import PDFTextExtractionNotAllowed def parse(Path,Save_name): parser = PDFParser(Path)
document = PDFDocument(parser) if not document.is_extractable:
raise PDFTextExtractionNotAllowed
else:
rsrcmgr = PDFResourceManager()
laparams = LAParams()
device = PDFPageAggregator(rsrcmgr,laparams=laparams)
interpreter = PDFPageInterpreter(rsrcmgr,device) for page in PDFPage.create_pages(document):
interpreter.process_page(page)
layout = device.get_result()
for x in layout:
if(isinstance(x,LTTextBoxHorizontal)):
with open('%s'%(Save_name),'a') as f:
results = x.get_text().encode('utf-8')
f.write(results +"\n") if __name__ == '__main__':
Path = open('word1-words.pdf','rb')
parse(Path,'1.txt')

  

 

五,python3.6中如何改进python2.7实现的代码

  问题一,reload的改进

import sys
reload(sys)
sys.setdefaultencoding(‘utf-8’)

  以上是python2的写法,但是在python3中这个需要已经不存在了,这么做也不会什么实际意义。

  在Python2.x中由于str和byte之间没有明显区别,经常要依赖于defaultencoding来做转换。 
  在python3中有了明确的str和byte类型区别,从一种类型转换成另一种类型要显式指定encoding。

  但是仍然可以使用这个方法代替

import importlib,sys
importlib.reload(sys)

  

  问题二,pdfminer模块的安装

  在python2.7中可以直接安装

pip install pdfminer

  在python3.6中就需要安装

pip install pdfminer3k

  

六   python3.6的源代码

import pyocr
import importlib
import sys
import time importlib.reload(sys)
time1 = time.time()
# print("初始时间为:",time1) import os.path
from pdfminer.pdfparser import PDFParser,PDFDocument
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import PDFPageAggregator
from pdfminer.layout import LTTextBoxHorizontal,LAParams
from pdfminer.pdfinterp import PDFTextExtractionNotAllowed text_path = r'words-words.pdf'
# text_path = r'photo-words.pdf' def parse():
'''解析PDF文本,并保存到TXT文件中'''
fp = open(text_path,'rb')
#用文件对象创建一个PDF文档分析器
parser = PDFParser(fp)
#创建一个PDF文档
doc = PDFDocument()
#连接分析器,与文档对象
parser.set_document(doc)
doc.set_parser(parser) #提供初始化密码,如果没有密码,就创建一个空的字符串
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内容
# doc.get_pages() 获取page列表
for page in doc.get_pages():
interpreter.process_page(page)
#接受该页面的LTPage对象
layout = device.get_result()
# 这里layout是一个LTPage对象 里面存放着 这个page解析出的各种对象
# 一般包括LTTextBox, LTFigure, LTImage, LTTextBoxHorizontal 等等
# 想要获取文本就获得对象的text属性,
for x in layout:
if(isinstance(x,LTTextBoxHorizontal)):
with open(r'2.txt','a') as f:
results = x.get_text()
print(results)
f.write(results +"\n") if __name__ == '__main__':
parse()
time2 = time.time()
print("总共消耗时间为:",time2-time1)

 

七   python读取PDF文档代码分析

  PDF格式不是规范格式. 尽管它被叫做"PDF文档", 但并不像word或者html文档。PDF的表现更像一张图片。PDF更像是在一张纸的各个准确的位置上把内容都摆放出来。大部分情况下,没有逻辑结构,比如句子或段落,并且不能自适应页面大小的调整。PDFMiner尝试通过猜测它们的布局来重建它们的结构,但是不保证一定能工作。我知道这样很难看,但是,PDF确实不够规范。

  下面这个图片是使用流程说明,我们将其分解来看

深入学习python解析并读取PDF文件内容的方法

    由于PDF文件有如此大和复杂的结构,完整解析PDF文件很费时费力。
好吧,大多数PDF工作中,很多模块是不需要加进来的。因此 PDFMiner
采用了一个懒惰分析的策略,就是只分析所需要的部分。解析时候,至少
需要2个核心类,PDFParser 和 PDFDocument。这两个模块配合其他
模块来使用。 PDFParser 从文件中获取数据 PDFDocument 存储文档数据结构到内存中 PDFPageInterpreter 解析page内容 PDFDevice 把解析到的内容转化为你需要的东西 PDFResourceManager存储共享资源,例如字体或图片

  

深入学习python解析并读取PDF文件内容的方法

  首先使用 open 方法或者  urlopen  打开本场文档或者网络文档(一般会这么做因为考虑到文档太大,对网络服务器负担也很大)生成文档对象,以下的方法之中的网络链接已经存在了。

  

# 获取文档对象
pdf0 = open('sampleFORtest.pdf','rb')
# pdf1 = urlopen('http://www.tencent.com/20160321.pdf')

  然后创建 文档解析器 和 PDF文档对象 并将他们相互关联

# 创建一个与文档关联的解析器
parser = PDFParser(pdf0) # 创建一个PDF文档对象
doc = PDFDocument() # 连接两者
parser.set_document(doc)
doc.set_parser(parser)

  对 PDF文档对象 进行初始化,如果文档本身进行了加密,则需要在加入 password 参数

# 文档初始化
doc.initialize('')

  深入学习python解析并读取PDF文件内容的方法

  先创建 PDF资源管理器 和 参数分析器

# 创建PDF资源管理器
resources = PDFResourceManager() # 创建参数分析器
laparam = LAParams()

  再创建一个 聚合器 ,并接收 PDF资源管理器  参数分析器 作为参数

# 创建一个聚合器,并接收资源管理器,参数分析器作为参数
device = PDFPageAggregator(resources,laparams=laparam)

  最后创建一个 页面解释器 ,将 PDF资源管理器 和 聚合器 作为参数

# 创建一个页面解释器
interpreter = PDFPageInterpreter(resources,device)

  这样 页面解释器 就具有对PDF文档进行编码,解释成Python能够识别的格式

深入学习python解析并读取PDF文件内容的方法

  最后呢,使用 PDF文档对象 的 get_pages()方法 从PDF文档中读取出页面集合,接着使用 页面解释器    对页面集合逐一读取,再调用 聚合器  的 get_result()方法 将页面逐一放置到 layout 之中,最后商用 layout 的 get_text()方法 获取每一页的 text。

for page in doc.get_pages():
# 使用页面解释器读取页面
interpreter.process_page(page)
# 使用聚合器读取页面页面内容
layout = device.get_result() for out in layout:
if hasattr(out,'get_text'): # 因为文档中不只有text文本
print(out.get_text())

  需要注意的是在PDF文档中不只有 text 还可能有图片等等,为了确保不出错先判断对象是否具有 get_text()方法

八,结果分析

  如果PDF文件中仅仅是文字,那么会完全解析出来,读出文字,存在一个TXT文档里面,但是要是出现了图片等东西,则不会读取到东西。

  本文做了三个实验,分别是PDF文档里面只存在文字,只存在图片,存在文字和图片。

  结果显示:

只存在文字的PDF 此程序会全部读取出文字
只存在图片的PDF 此程序不会读取出任何东西
存在图片和文字 此程序只会读出文字,不会识别图片

  所以说,图片的文字识别,不能只单纯的使用pdfminer这个库,还需要图片处理等相关技术。

九,PDF解析模块-PDFMiner开发手册

PDF格式不是规范格式. 尽管它被叫做"PDF文档", 但并不像word或者html文档。PDF的表现更像一张图片。PDF更像是在一张纸的各个准确的位置上把内容都摆放出来。大部分情况下,没有逻辑结构,比如句子或段落,并且不能自适应页面大小的调整。PDFMiner尝试通过猜测它们的布局来重建它们的结构,但是不保证一定能工作。我知道这样很难看,但是,PDF确实不够规范。

更多关于PDF内部结构的技术详情,请见《如何手工提取PDF内容》。

http://www.youtube.com/watch?v=k34wRxaxA_c
http://www.youtube.com/watch?v=_A1M4OdNsiQ
http://www.youtube.com/watch?v=sfV_7cWPgZE

由于PDF文件有如此大和复杂的结构,完整解析PDF文件很费时费力。好吧,大多数PDF工作中,很多模块是不需要加进来的。因此
PDFMiner 采用了一个懒惰分析的策略,就是只分析所需要的部分。解析时候,至少需要2个核心类,PDFParser 和
PDFDocument。这两个模块配合其他模块来使用。

PDFParser     从文件中获取数据

PDFDocument   存储文档数据结构到内存中

PDFPageInterpreter 解析page内容

PDFDevice    把解析到的内容转化为你需要的东西

PDFResourceManager存储共享资源,例如字体或图片

布局分析把pdf文档中每一页返回为一个 LTPage 对象. 该对象包含该页面中的子对象,格式化为树形结构。

下图显示了这些对象之间的关系。

深入学习python解析并读取PDF文件内容的方法

LTPage

代表一个完整的页面。可以包含子对象,例如LTTextBox,LTFigure,LTImage,LTRect,LTCurve和LTLine.

LTTextBox
它包含 LTTextLine 对象的列表
代表一组被包含在矩形区域中的文本
需要注意的是,该box是根据几何学分析得到的,并不一定准确地表现为该文本的逻辑范围
get_text()方法可以返回文本内容

LTTextLine
包含一个LTChar对象的列表,表现为单行文本
字符表现为一行或一列,取决于文本书写方式
get_text()方法返回文本内容

LTChar / LTAnno
代表一个在文本中的真实的字母,作为一个unicode字符串
LTChar 对象有真实的分隔符
LTAnno 对象没有,是虚拟分隔符,按照两个字符之间的关系,布局分析器插入虚拟分隔符

LTFigure
代表一个被PDF Form对象使用的区域
pdf form适用于目前的图表(present figures)或者页面中植入的另一个pdf文档图片。LTFigure对象可以递归

LTImage
代表一个图形对象。可以是JPEG或者其他格式,但PDFMiner目前没有花太多精力在图形对象上。

LTLine
代表一根直线。用来分割文本或图表(figures)。

LTRect
代表一个矩形。
用来框住别的图片或者图表。

LTCurve
代表一个贝塞尔曲线。

也可以从下面URL获得更多完整的示例。

http://denis.papathanasiou.org/?p=343

深入学习python解析并读取PDF文件内容的方法的更多相关文章

  1. 深入学习Python解析并解密PDF文件内容的方法

    前面学习了解析PDF文档,并写入文档的知识,那篇文章的名字为深入学习Python解析并读取PDF文件内容的方法. 链接如下:https://www.cnblogs.com/wj-1314/p/9429 ...

  2. robotframework 测试工具添加PDF文件内容匹配插件

    robotframework  这个需要了解的请度娘.本文实现的是一个小功能.大体分为如下几个步骤 1)给定一个pdf文件. 2)读取pdf文件内容,并解析为文本内容. 3)通过给定的内容,比对pdf ...

  3. 【转】Python 深入浅出 - PyPDF2 处理 PDF 文件

    实际应用中,可能会涉及处理 pdf 文件,PyPDF2 就是这样一个库,使用它可以轻松的处理 pdf 文件,它提供了读,割,合并,文件转换等多种操作. 文档地址:http://pythonhosted ...

  4. python解析VOC的xml文件并转成自己需要的txt格式

    在进行神经网络训练的时候,自己标注的数据集往往会有数据量不够大以及代表性不强等问题,因此我们会采用开源数据集作为训练,开源数据集往往具有特定的格式,如果我们想将开源数据集为我们所用的话,就需要对其格式 ...

  5. Unity的Json解析<一>--读取Json文件

    本文章由cartzhang编写,转载请注明出处. 所有权利保留. 文章链接:http://blog.csdn.net/cartzhang/article/details/50373558 作者:car ...

  6. 利用Python将多个PDF文件合并

    from PyPDF2 import PdfFileMerger import os files = os.listdir()#列出目录中的所有文件 merger = PdfFileMerger() ...

  7. Python基础之读取ini文件

    基本使用方法 第一步:准备一份INI文件.如test1.ini [ITEMS] item1=1 item2=2 item3=3 item4=4 [ITEM1] test1=aaa [ITEM2] te ...

  8. pdf文件内容查看器 -- 采用wpf开发

    前言 pdf是一种应用非常广的版式文档格式,已成为事实上的国际标准.关于pdf格式的文章汗牛充栋,本文也是关于pdf格式的文章,但是本文不是纸上谈兵:本人这几周一直研究pdf格式内容,不但对pfd格式 ...

  9. PHP读取Excel文件内容

    PHP读取Excel文件内容   项目需要读取Excel的内容,从百度搜索了下,主要有两个选择,第一个是PHPExcelReader,另外一个是PHPExcel.   PHPExcelReader比较 ...

随机推荐

  1. [阅读笔记]Software optimization resources

    http://www.agner.org/optimize/#manuals 阅读笔记Optimizing software in C++   7. The efficiency of differe ...

  2. ccc 调试方法

    当修改完一个函数,但是不知道哪个函数调用的时候没有传递正确的参数的时候 需要找出调用这个函数的所有语句,于是我注释掉这个函数就可以了

  3. Bootstrap3生成响应式的特价商品展示布局

    在线演示 本地下载 在线前端调试地址,大家可以在线自己调试. 在线调试唯一地址:http://www.gbtags.com/gb/debug/fa35e396-0a04-4b73-9bfc-c6334 ...

  4. 单线程模型中Message、Handler、Message Queue、Looper之间的关系

    1. Android进程 在了解Android线程之前得先了解一下Android的进程.当一个程序第一次启动的时候,Android会启动一个LINUX进程和一个主线程.默认的情况下,所有该程序的组件都 ...

  5. 把nc v6的源码看懂

    看懂nc v6的源码! 碧桂园全部的正式环境的补丁都在我手里. 2015-11-18 2:33 谢谢两位一起努力的兄弟 谢谢超哥,谢谢祈冰哥,谢谢连老师,陈明大哥,谢谢龙哥,珍玉,谢谢廖生哥,谢谢林春 ...

  6. 【转】 Ubuntu samba服务器搭建及测试--不错

    原文网址:http://blog.csdn.net/longfeey/article/details/5937968 Ubuntu samba服务配置是很不错的文件应用很有学习价值, 这里我主要讲解U ...

  7. Spring再接触 Annotation part1

    使用annotation首先得加这两条代码 beans.xml <?xml version="1.0" encoding="UTF-8"?> &lt ...

  8. Centos7中docker开启远程访问

    在作为docker远程服务的centos7机器中配置: 1.在/usr/lib/systemd/system/docker.service,配置远程访问.主要是在[Service]这个部分,加上下面两 ...

  9. java http get、post请求

    package com.zpark.test; import org.junit.Test; import java.io.BufferedReader; import java.io.IOExcep ...

  10. 关于快速沃尔什变换(FWT)的一些个人理解

    定义 FWT是一种快速完成集合卷积运算的算法. 它可以用于求解类似 $C[i]=\sum\limits_{j⊗k=i}A[j]*B[k]$ 的问题. 其中⊗代表位运算中的|,&,^的其中一种. ...