新闻动态

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

发布日期:2022-03-14 18:09 | 文章来源:CSDN

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

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

01需求描述

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

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

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

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

02前置知识和逻辑梳理

2.1 PyPDF2 模块实现合并

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

fromPyPDF2importPdfFileReader,PdfFileWriter

这里导入了两个方法:

  • PdfFileReader 可以理解为读取器
  • PdfFileWriter 可以理解为写入器

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

  • 读取器将所有pdf读取一遍
  • 读取器将读取的内容交给写入器
  • 写入器统一输出到一个新pdf

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

2.2 获取与添加页面

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

  • .getPage 获取特定页
  • .addPage 添加特定页

2.3 图片和文字的处理

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

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

  • 利用 pdfplumber 打开PDF 文件
  • 获取指定的页,或者遍历每一页
  • 利用 .extract_text() 方法提取当前页的文字
  • 判断 “战略” 是否在提取的文字中

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

03代码实现

3.1 需求一的实现

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

fromPyPDF2importPdfFileReader,PdfFileWriter
importpdfplumber

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

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

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

withpdfplumber.open(path+r'\公司年报.PDF')aspdf:
foriinrange(pdf_reader.getNumPages()):
page=pdf.pages[i]
print(page.extract_text())

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

withpdfplumber.open(path+r'\公司年报.PDF')aspdf:
foriinrange(pdf_reader.getNumPages()):
page=pdf.pages[i]
print(page.extract_text())
if'战略'inpage.extract_text():
pdf_writer.addPage(pdf_reader.getPage(i))
print(i+1,page.extract_text())

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

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

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

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

fromPyPDF2importPdfFileReader,PdfFileWriter
importpdfplumber
 
path=r'C:\xxx'
pdf_writer=PdfFileWriter()
pdf_reader=PdfFileReader(path+r'\公司年报.PDF')
 
withpdfplumber.open(path+r'\公司年报.PDF')aspdf:
foriinrange(pdf_reader.getNumPages()):
page=pdf.pages[i]
print(page.extract_text())
if'战略'inpage.extract_text():
pdf_writer.addPage(pdf_reader.getPage(i))
print(i+1,page.extract_text())
 
withopen(path+r'\new_公司年报1.pdf','wb')asout:
pdf_writer.write(out)

3.2 需求二的实现

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

fromPyPDF2importPdfFileReader,PdfFileWriter
importfitz
importre
importos

指定文件所在的路径:

path = r'C:\xxxxxx'

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

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

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

pdf_reader=PdfFileReader(path+r'\公司年报.PDF')
forpageinpage_lst:
pdf_writer=PdfFileWriter()
pdf_writer.addPage(pdf_reader.getPage(page))
withopen(path+r'\公司年报_{}.pdf'.format(page+1),'wb')asout:
pdf_writer.write(out)

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

fromPyPDF2importPdfFileReader,PdfFileWriter
importfitz
importre
importos
 
path=r'C:\xxx'
 
page_lst=[]
checkImg=r"/Subtype(?=*/Image)"
pdf=fitz.open(path+r'\公司年报.PDF')
lenXREF=pdf._getXrefLength()
foriinrange(lenXREF):
text=pdf._getXrefString(i)
isImage=re.search(checkImg,text)
ifisImage:
page_lst.append(i)
 
print(page_lst)
 
pdf_reader=PdfFileReader(path+r'\公司年报.PDF')
forpageinpage_lst:
pdf_writer=PdfFileWriter()
pdf_writer.addPage(pdf_reader.getPage(page))
withopen(path+r'\公司年报_{}.pdf'.format(page+1),'wb')asout:
pdf_writer.write(out)

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

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

国外稳定服务器

版权声明:本站文章来源标注为YINGSOO的内容版权均为本站所有,欢迎引用、转载,请保持原文完整并注明来源及原文链接。禁止复制或仿造本网站,禁止在非www.yingsoo.com所属的服务器上建立镜像,否则将依法追究法律责任。本站部分内容来源于网友推荐、互联网收集整理而来,仅供学习参考,不代表本站立场,如有内容涉嫌侵权,请联系alex-e#qq.com处理。

相关文章

实时开通

自选配置、实时开通

免备案

全球线路精选!

全天候客户服务

7x24全年不间断在线

专属顾问服务

1对1客户咨询顾问

在线
客服

在线客服:7*24小时在线

客服
热线

400-630-3752
7*24小时客服服务热线

关注
微信

关注官方微信
顶部