PDFMiner简介
pdf提取目前的解决方案大致只有pyPDF和PDFMiner。据说PDFMiner更适合文本的解析,首先说明的是解析PDF是非常蛋疼的事,即使是PDFMiner对于格式不工整的PDF解析效果也不怎么样,所以连PDFMiner的开发者都吐槽PDF is evil. 不过这些并不重要。
PDFMiner是一个可以从PDF文档中提取信息的工具。与其他PDF相关的工具不同,它注重的完全是获取和分析文本数据。PDFMiner允许你获取某一页中文本的准确位置和一些诸如字体、行数的信息。它包括一个PDF转换器,可以把PDF文件转换成HTML等格式。它还有一个扩展的PDF解析器,可以用于除文本分析以外的其他用途。
PDFMiner内置两个好用的工具:pdf2txt.py和dumppdf.py
- pdf2txt.py从PDF文件中提取所有文本内容。但不能识别画成图片的文本,这需要特征识别。对于加密的PDF你需要提供一个密码才能解析,对于没有提取权限的PDF文档你得不到任何文本。
- dumppdf.py把PDF文件内容变成pseudo-XML格式。这个程序主要用于debug,但是它也可能用于提取一些有意义的内容(比如图片)。
PDFMiner在python2中名为PDFMiner,在python3中名为PDFMiner3k,分别上链接
PDFMiner 官方主页:https://euske.github.io/pdfminer/
PDFMiner github主页:https://github.com/euske/pdfminerpdfminer3k 官方主页:https://pypi.org/project/pdfminer3k/
pdfminer3k github主页:https://github.com/jaepil/pdfminer3k
解析pdf文件用到的类:
- PDFParser:PDF文档分析器:从一个文件中获取数据
- PDFDocument:PDF文档对象:保存获取的数据,和PDFParser是相互关联的
- PDFPageInterpreter:PDF文档解析器:处理页面内容,变成Python可以解析
- PDFResourceManager:PDF资源管理器:用于存储共享资源,如字体或图像。
- PDFDevice: 将其翻译成你需要的格式
- LAParams:PDF参数分析器:分析pdf文件参数
- PDFPageAggregator:PDF聚合器:读取获取的文档对象
他们之间的关系图如下:
布局分析返回的PDF文档中的每个页面LTPage对象。这个对象和页内包含的子对象,形成一个树结构,如图所示:
- LTPage :表示整个页。可能会含有LTTextBox,LTFigure,LTImage,LTRect,LTCurve和LTLine子对象。
- LTTextBox:表示一组文本块可能包含在一个矩形区域。注意此box是由几何分析中创建,并且不一定
表示该文本的一个逻辑边界。它包含LTTextLine对象的列表。使用 get_text()方法返回的文本内容。 - LTTextLine :包含表示单个文本行LTChar对象的列表。字符对齐要么水平或垂直,取决于文本的写入模式。
get_text()方法返回的文本内容。 - LTChar
- LTAnno:在文本中实际的字母表示为Unicode字符串(?)。需要注意的是,虽然一个LTChar对象具有实际边界,
LTAnno对象没有,因为这些是“虚拟”的字符,根据两个字符间的关系(例如,一个空格)由布局分析后插入。 - LTImage:表示一个图像对象。嵌入式图像可以是JPEG或其它格式,但是目前PDFMiner没有放置太多精力在图形对象。
- LTLine:代表一条直线。可用于分离文本或附图。
- LTRect:表示矩形。可用于框架的另一图片或数字。
LTCurve:表示一个通用的
Bezier曲线
一个简单的示例
# encoding: utf-8
import sys
import importlib
importlib.reload(sys)
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 PDFTextExtractionNotAllowedpath ="C:\\Users\\admin\\Desktop\\t.pdf"
def parse():fp = open(path, 'rb') #用文件对象来创建一个pdf文档分析器PDFParserpraser = PDFParser(fp)# 创建一个PDF文档PDFDocumentdoc = PDFDocument()# 连接分析器 与文档对象praser.set_document(doc)doc.set_parser(praser)# 提供初始化密码,如果没有密码 就创建一个空的字符串doc.initialize()# 检测文档是否提供txt转换,不提供就忽略if not doc.is_extractable:raise PDFTextExtractionNotAllowedelse:# 创建PDf 资源管理器 来管理共享资源PDFResourceManagerrsrcmgr = PDFResourceManager()# 创建一个PDF设备对象LAParamslaparams = LAParams()# 创建聚合器,用于读取文档的对象PDFPageAggregatordevice = PDFPageAggregator(rsrcmgr, laparams=laparams)# 创建一个PDF解释器对象,对文档编码,解释成Python能够识别的格式:PDFPageInterpreterinterpreter = PDFPageInterpreter(rsrcmgr, device)# 循环遍历列表,每次处理一个page的内容for page in doc.get_pages(): # doc.get_pages() 获取page列表# 利用解释器的process_page()方法解析读取单独页数interpreter.process_page(page)# 这里layout是一个LTPage对象,里面存放着这个page解析出的各种对象,一般包括LTTextBox, LTFigure, LTImage, LTTextBoxHorizontal等等,想要获取文本就获得对象的text属性,# 使用聚合器get_result()方法获取页面内容layout = device.get_result()for x in layout:if (isinstance(x, LTTextBoxHorizontal)):#需要写出编码格式with open(r'C:\Users\admin\Desktop\1.txt', 'a',encoding='utf-8') as f:results = x.get_text()f.write(results + '\n')if __name__ == '__main__':parse()
或者使用官方的一个例子,简单写如下
rsrcmgr = PDFResourceManager(caching=caching) # 创建一个PDF资源管理器对象来存储共赏资源
outfp = io.open(outfile, 'wt', encoding=codec, errors='ignore') #指定outfile
device = XMLConverter(rsrcmgr, outfp, laparams=laparams, outdir=outdir)
fp = io.open(file, 'rb') #来创建一个pdf文档分析器
process_pdf(rsrcmgr, device, fp, pagenos, maxpages=maxpages, password=password, caching=caching, check_extractable=True) #调用process_pdf
fp.close()
device.close()
outfp.close()
参考链接: https://blog.csdn.net/liuqingpeng_1/article/details/79560753 https://www.zhangshengrong.com/p/Z9a2AAy1Vk/ https://blog.csdn.net/qq_29750461/article/details/80011255 https://blog.csdn.net/sinat_37967865/article/details/80145487