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

顾星河
顾星河
发布时间:2026-10-14 | 2人浏览过
原创

本文通过两个真实需求,演示如何使用Python提取PDF中指定内容并生成新文件。需求一提取包含特定文字“战略”的页面并合并,需求二提取包含图片的页面并单独保存。文章详细梳理了PyPDF2、pdfplumber和fitz模块的逻辑,提供了完整的代码实现,并提示图片识别方法的局限性。

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

然而,在实际应用中,我们往往无法预先知道需要提取的具体页号,而是希望将包含指定内容的页面提取出来,合并生成一个新的PDF文件。本文将通过两个真实的需求案例来进行详细讲解。

01需求描述

假设我们有一份包含286页的上市公司公开年报PDF文件,其大致内容如下:

现在,我们需要利用Python完成以下两个具体需求:

“

需求一:提取所有包含“战略”二字的页面,并将它们合并生成一个新的PDF文件。

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

”

02前置知识和逻辑梳理

2.1 PyPDF2 模块实现合并

使用PyPDF2导入模块的代码通常如下所示:


from PyPDF2 import PdfFileReader, PdfFileWriter

这里我们导入了两个核心方法:

  • PdfFileReader 可以理解为读取器,负责读取PDF文件。
  • PdfFileWriter 可以理解为写入器,负责将处理后的内容写入新的PDF文件。

利用PyPDF2实现合并的基本逻辑如下:

  • 首先,读取器会将所有PDF页面读取到内存中。
  • 接着,读取器将读取到的内容逐页传递给写入器。
  • 最后,写入器将所有接收到的页面统一输出到一个新的PDF文件中。

需要注意一个隐含知识点:读取器只能将读取的内容一页一页地交给写入器,无法直接批量操作。

2.2 获取与添加页面

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

  • .getPage 用于获取特定页。
  • .addPage 用于添加特定页到写入器中。

2.3 图片和文字的处理

要实现本文的需求,还需要完成一个重要的判断步骤:确定页面中是否包含特定的文字或图片。

判断是否包含特定文字相对简单,只需在遍历每一页时提取其中的文本,然后进行字符串层面的判断即可。代码思路如下:

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

判断是否包含图片的思路与上述类似,但方法不同。对于图片,我们考虑使用正则表达式进行识别,配合fitz和re模块,具体实现见下文代码。

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。所有提取的页面均包含“战略”二字:

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


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 相关产品和应用

全部下载

专题列表