Python处理pdf文件 - pdfminer、pdfplumber

pdfminer3k

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

from pdfminer.pdfparser import PDFParser, PDFDocument
from pdfminer.pdfparser import PDFPage
from pdfminer.pdfinterp import PDFResourceManager, PDFTextExtractionNotAllowed
from pdfminer.pdfinterp import PDFPageInterpreter
from pdfminer.pdfdevice import PDFDevice
from pdfminer.layout import LAParams
from pdfminer.converter import PDFPageAggregator


fp = open("笨办法学Python(第三版).pdf", "rb")
parser = PDFParser(fp)     # 创建一个与文档相关联的解释器
doc = PDFDocument()        # PDF文档对象,提供密码初始化,没有就不用带password参数。
parser.set_document(doc)   # 链接解释器和文档对象
doc.set_parser(parser)
doc.initialize()           # 初始化文档

# 检查文件是否允许文本提取
if not doc.is_extractable:
    raise PDFTextExtractionNotAllowed

resource = PDFResourceManager()    # 创建PDF资源管理器对象来存储共享资源
laparam = LAParams()               # 参数分析器
device = PDFPageAggregator(resource, laparams=laparam)    # 创建一个聚合器
interpreter = PDFPageInterpreter(resource, device)        # 创建PDF页面解释器

for page in doc.get_pages():
    interpreter.process_page(page)  # 使用页面解释器来读取
    layout = device.get_result()   # 使用聚合器来获取内容
    for out in layout:
        if hasattr(out, "get_text"):
            print(out.get_text())    #打印结果

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

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 类型的二维数组

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

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()

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

当然对于不同的 pdf,可能需要不同的处理,实际情况还是要自己分析。

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

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

  • 5
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值