Python提取PDF指定内容并生成新文件

作者:程序员启航 时间:2022-11-09 19:44:00 

在之前的Python办公自动化案专题中,我们已经介绍了如何有选择的提取某些页面进行合并。

但是很多时候,我们并不会预知希望提取的页号,而是希望将包含指定内容的页面提取合并为新PDF,本文就以两个真实需求为例进行讲解。

01需求描述

数据是一份有286页的上市公司公开年报PDF,大致如下

Python提取PDF指定内容并生成新文件

现在需要利用 Python 完成以下两个需求

需求一:提取所有包含 战略 二字的页面并合并新PDF

需求二:提取所有包含图片的页面,并分别保存为 PDF 文件

02前置知识和逻辑梳理

2.1 PyPDF2 模块实现合并

PyPDF2 导入模块的代码常常是:


from PyPDF2 import PdfFileReader, PdfFileWriter

这里导入了两个方法:

  • PdfFileReader 可以理解为读取器

  • PdfFileWriter 可以理解为写入器

利用 PyPDF2 实现合并运用的一下逻辑:

  • 读取器将所有pdf读取一遍

  • 读取器将读取的内容交给写入器

  • 写入器统一输出到一个新pdf

隐含知识点:读取器只能将读取的内容一页一页交给写入器

2.2 获取与添加页面

之前我们的推文中提到这两个代码,下面列出作为复习:

  • .getPage 获取特定页

  • .addPage 添加特定页

2.3 图片和文字的处理

要实现本文的需求还要做到很重要的一个判断:确定页面中有无包含的文字或图片

判断是否包含特定的文字比较简单,遍历每一页的时候都将包含的文本抽提出,做字符串层面的判断即可,代码思路:

  • 利用 pdfplumber 打开PDF 文件

  • 获取指定的页,或者遍历每一页

  • 利用 .extract_text() 方法提取当前页的文字

  • 判断 “战略” 是否在提取的文字中

判断是否包含图片,思路和上面是类似的,但方法不同。图片考虑用正则的方法识别,用 fitzre 配合,具体见下文代码

03代码实现

3.1 需求一的实现

首先来完成需求一的任务,导入需要用到的库:读取写入PDF文件的 PyPDF2 以及抽提文本的 pdfplumber


from PyPDF2 import PdfFileReader, PdfFileWriter
import pdfplumber

指定文件所在的路径,同时初始化写入器,将文件交给读取器:


path = r'C:\xxxxxx'
pdf_writer = PdfFileWriter()
pdf_reader = PdfFileReader(path + r'\公司年报.PDF')

以上下文管理器形式通过 pdfplumber 打开文件,同时用 .getNumPages 获取读取器的最大页利于遍历每一页来抽提文字:


with pdfplumber.open(path + r'\公司年报.PDF') as pdf:
    for i in range(pdf_reader.getNumPages()):
        page = pdf.pages[i]
        print(page.extract_text())

我们抽提文字的目的是用来判断,将符合要求的页码作为读取器 .getPage 的参数,最后用 .addPage 交给写入器:


with pdfplumber.open(path + r'\公司年报.PDF') as pdf:
    for i in range(pdf_reader.getNumPages()):
        page = pdf.pages[i]
        print(page.extract_text())
        if '战略' in page.extract_text():
            pdf_writer.addPage(pdf_reader.getPage(i))
            print(i + 1, page.extract_text())

完成识别后让写入器输出为需要的文件名:


with open(path + r'\new_公司年报.pdf', 'wb') as out:
    pdf_writer.write(out)

至此,我们就完成了包含特定文字内容页面的提取,并整合成一个PDF。所有的页面均包含“战略”二字:

Python提取PDF指定内容并生成新文件

Python提取PDF指定内容并生成新文件

需求一完整代码如下,感兴趣的读者可以自行研究


from PyPDF2 import PdfFileReader, PdfFileWriter
import pdfplumber

path = r'C:\xxx'
pdf_writer = PdfFileWriter()
pdf_reader = PdfFileReader(path + r'\公司年报.PDF')

with pdfplumber.open(path + r'\公司年报.PDF') as pdf:
    for i in range(pdf_reader.getNumPages()):
        page = pdf.pages[i]
        print(page.extract_text())
        if '战略' in page.extract_text():
            pdf_writer.addPage(pdf_reader.getPage(i))
            print(i + 1, page.extract_text())

with open(path + r'\new_公司年报1.pdf', 'wb') as out:
    pdf_writer.write(out)

3.2 需求二的实现

接下来完成需求二的任务。首先导入需要的库:


from PyPDF2 import PdfFileReader, PdfFileWriter
import fitz
import re
import os

指定文件所在的路径:


path = r'C:\xxxxxx'

正则识别图片的部分不细讲,之前的推文已经介绍过,我们直接看代码:


page_lst = []
checkImg = r"/Subtype(?= */Image)"
pdf = fitz.open(path + r'\公司年报.PDF')
lenXREF = pdf._getXrefLength()

for i in range(lenXREF):
    text = pdf._getXrefString(i)
    isImage = re.search(checkImg, text)
    if isImage:
        page_lst.append(i)

print(page_lst)

获取到所有包含图片的页面后,再结合读取器和写入器的配合就能完成新 PDF 的产生。注意本需求是所有图片单独输出,因此获取到页面后交给写入器直接输出成文件:


pdf_reader = PdfFileReader(path + r'\公司年报.PDF')
for page in page_lst:
    pdf_writer = PdfFileWriter()
    pdf_writer.addPage(pdf_reader.getPage(page))
    with open(path + r'\公司年报_{}.pdf'.format(page + 1), 'wb') as out:
        pdf_writer.write(out)

至此也完成了第二个需求。需要说明的是目前没有非常完美提取PDF图片的方法,本案例介绍的方法识别图片也并不稳定。读者可以利用自己的数据多做尝试。完整代码如下:


from PyPDF2 import PdfFileReader, PdfFileWriter
import fitz
import re
import os

path = r'C:\xxx'

page_lst = []
checkImg = r"/Subtype(?= */Image)"
pdf = fitz.open(path + r'\公司年报.PDF')
lenXREF = pdf._getXrefLength()
for i in range(lenXREF):
    text = pdf._getXrefString(i)
    isImage = re.search(checkImg, text)
    if isImage:
        page_lst.append(i)

print(page_lst)

pdf_reader = PdfFileReader(path + r'\公司年报.PDF')
for page in page_lst:
    pdf_writer = PdfFileWriter()
    pdf_writer.addPage(pdf_reader.getPage(page))
    with open(path + r'\公司年报_{}.pdf'.format(page + 1), 'wb') as out:
        pdf_writer.write(out)

实现这两个单个需求后,就可以将相关代码封装并结合os等模块实现批量操作,解放双手。

来源:https://blog.csdn.net/aaahtml/article/details/117650641

标签:Python,提取,PDF
0
投稿

猜你喜欢

  • Python使用sqlite3第三方库读写SQLite数据库的方法步骤

    2024-01-23 06:31:39
  • python3获取当前文件的上一级目录实例

    2021-06-03 02:22:22
  • Vue+Websocket简单实现聊天功能

    2024-04-30 10:29:50
  • 准备SQL Server 2008透明数据加密

    2009-01-22 14:18:00
  • Python基础-特殊方法整理详解

    2022-08-11 00:46:31
  • 基于JS实现动态跟随特效的示例代码

    2023-06-30 11:15:16
  • Golang实现http重定向https

    2024-04-26 17:27:57
  • Python如何使用argparse模块处理命令行参数

    2023-02-03 18:10:20
  • python 绘制正态曲线的示例

    2023-08-22 10:52:14
  • SQL Server比较常见数据类型详解

    2024-01-26 11:28:48
  • MySQL limit使用方法以及超大分页问题解决

    2024-01-24 21:46:56
  • Python正则表达式中的量词符号与组问题小结

    2022-12-14 15:24:24
  • sql 判断函数、存储过程是否存在的代码整理

    2024-01-28 20:09:53
  • sql基本查询语句介绍

    2008-05-21 13:58:00
  • PHP操作数组的一些函数整理介绍

    2023-11-24 14:24:17
  • 深入透析样式表滤镜(下)

    2011-06-14 09:49:19
  • python中元类用法实例

    2023-10-24 19:12:29
  • 深入理解Vue 的条件渲染和列表渲染

    2024-04-09 10:46:37
  • Yii2框架实现登陆添加验证码功能示例

    2023-11-21 11:36:32
  • php的PDO事务处理机制实例分析

    2024-05-11 09:45:30
  • asp之家 网络编程 m.aspxhome.com