Python 第三方模块之 PDFMiner(pdf信息提取)

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/pdfminer

pdfminer3k  官方主页: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 PDFTextExtractionNotAllowed

path ="C:\\Users\\admin\\Desktop\\t.pdf"
def parse():
    fp = open(path, 'rb') 
    #用文件对象来创建一个pdf文档分析器PDFParser
    praser = PDFParser(fp)
    # 创建一个PDF文档PDFDocument
    doc = PDFDocument()
    # 连接分析器 与文档对象
    praser.set_document(doc)
    doc.set_parser(praser)

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

    # 检测文档是否提供txt转换,不提供就忽略
    if not doc.is_extractable:
        raise PDFTextExtractionNotAllowed
    else:
        # 创建PDf 资源管理器 来管理共享资源PDFResourceManager
        rsrcmgr = PDFResourceManager()
        # 创建一个PDF设备对象LAParams
        laparams = LAParams()
        # 创建聚合器,用于读取文档的对象PDFPageAggregator
        device = PDFPageAggregator(rsrcmgr, laparams=laparams)
        # 创建一个PDF解释器对象,对文档编码,解释成Python能够识别的格式:PDFPageInterpreter
        interpreter = 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
参与评论 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:博客之星2020 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值