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


Posted in Python onJune 09, 2021

在之前的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等模块实现批量操作,解放双手。

到此这篇关于Python提取PDF指定内容并生成新文件的文章就介绍到这了,更多相关Python提取PDF指定内容内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python单体模式的几种常见实现方法详解
Jul 28 Python
python MysqlDb模块安装及其使用详解
Feb 23 Python
Windows 7下Python Web环境搭建图文教程
Mar 20 Python
解决Matplotlib图表不能在Pycharm中显示的问题
May 24 Python
python 脚本生成随机 字母 + 数字密码功能
May 26 Python
利用python打开摄像头及颜色检测方法
Aug 03 Python
Python redis操作实例分析【连接、管道、发布和订阅等】
May 16 Python
使用jupyter notebook将文件保存为Markdown,HTML等文件格式
Apr 14 Python
jupyter notebook读取/导出文件/图片实例
Apr 16 Python
Python 如何测试文件是否存在
Jul 31 Python
python 中的9个实用技巧,助你提高开发效率
Aug 30 Python
Python用户自定义异常的实现
Dec 25 Python
Python激活Anaconda环境变量的详细步骤
Jun 08 #Python
Python序列化与反序列化相关知识总结
Jun 08 #Python
浅谈怎么给Python添加类型标注
Python如何导出导入所有依赖包详解
Jun 08 #Python
OpenCV-Python实现油画效果的实例
OpenCV-Python实现图像平滑处理操作
OpenCV-Python模板匹配人眼的实例
You might like
IE 条件注释详解总结(附实例代码)
2009/08/29 Javascript
Js获取事件对象代码
2010/08/05 Javascript
如何让页面在打开时自动刷新一次让图片全部显示
2012/12/17 Javascript
浅析js中的浮点型运算问题
2014/01/06 Javascript
javascript入门之数组[新手必看]
2016/11/21 Javascript
JavaScript中从setTimeout与setInterval到AJAX异步
2017/02/13 Javascript
JavaScript中的this陷阱的最全收集并整理(没有之一)
2017/02/21 Javascript
jquery表单提交带错误信息提示效果
2017/03/09 Javascript
JS中移除非数字最多保留一位小数
2018/05/09 Javascript
详解vue-router 命名路由和命名视图
2018/06/01 Javascript
Vue源码探究之状态初始化
2018/11/14 Javascript
jQuery实现适用于移动端的跑马灯抽奖特效示例
2019/01/18 jQuery
jQuery实现简单的Ajax调用功能示例
2019/02/15 jQuery
解决ele ui 表格表头太长问题的实现
2019/11/13 Javascript
vue微信分享插件使用方法详解
2020/02/18 Javascript
使用python解析xml成对应的html示例分享
2014/04/02 Python
从零学python系列之浅谈pickle模块封装和拆封数据对象的方法
2014/05/23 Python
Python利用递归实现文件的复制方法
2018/10/27 Python
python执行CMD指令,并获取返回的方法
2018/12/19 Python
解决pycharm不能自动补全第三方库的函数和属性问题
2020/03/12 Python
pandas dataframe 中的explode函数用法详解
2020/05/18 Python
推荐技术人员一款Python开源库(造数据神器)
2020/07/08 Python
详解向scrapy中的spider传递参数的几种方法(2种)
2020/09/28 Python
linux centos 7.x 安装 python3.x 替换 python2.x的过程解析
2020/12/14 Python
selenium+headless chrome爬虫的实现示例
2021/01/08 Python
皇家阿尔伯特瓷器美国官网:Royal Albert美国
2020/02/16 全球购物
Chupi官网:在爱尔兰手工制作的订婚、结婚戒指和精美珠宝
2020/09/28 全球购物
结婚喜宴主持词
2014/03/14 职场文书
文科毕业生自荐书范文
2014/04/17 职场文书
好学生评语大全
2014/05/05 职场文书
公共机构节能宣传周活动总结
2014/07/09 职场文书
我的职业生涯规划:打造自己的运动帝国
2014/09/18 职场文书
购房个人委托书范本
2014/10/11 职场文书
2014年城市管理工作总结
2014/12/02 职场文书
自主招生英文自荐信
2015/03/25 职场文书
vue中 this.$set的使用详解
2021/11/17 Vue.js