如何用Python高效提取PDF特定内容并生成新PDF文件?

2026-05-28 15:301阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1869个文字,预计阅读时间需要8分钟。

如何用Python高效提取PDF特定内容并生成新PDF文件?

在众多场合,我们往往不会预知期望提取的页码,而是希望将包含指定内容的页面合并为新的PDF,并提取文本。以下以两个实际需求为例进行讲解。

案例一:合并包含特定关键词的页面

假设我们需要将文档中所有包含技术交流关键词的页面合并为一个PDF。

1. 使用PDF阅读器打开文档。

2.使用搜索功能查找技术交流。

3.将所有搜索结果页面复制粘贴到一个新的PDF文档中。

案例二:提取特定章节的文本

假设我们需要从文档中提取第一章和第二章的内容。

1. 定位到第一章的起始页。

2.按住鼠标左键,拖动至第二章的结束页,选择整个章节内容。

3.复制选中的内容,粘贴到文本编辑器中。

注意:以上操作的具体步骤可能因使用的软件和设备而异。


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

资料、代码、技术交流,文末获取

01 需求描述

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

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


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

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


02 前置知识和逻辑梳理

2.1​​PyPDF2​​ 模块实现合并

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

from PyPDF2 import PdfFileReader, PdfFileWriter

这里导入了两个方法:

  • ​​PdfFileReader​​ 可以理解为读取器
  • ​​PdfFileWriter​​ 可以理解为写入器
  • 利用 ​​PyPDF2​​ 实现合并运用的一下逻辑:

  • 读取器将所有pdf读取一遍
  • 读取器将读取的内容交给写入器
  • 写入器统一输出到一个新pdf
  • 隐含知识点:读取器只能将读取的内容一页一页交给写入器

    2.2 获取与添加页面

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

    如何用Python高效提取PDF特定内容并生成新PDF文件?

  • ​​.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等模块实现批量操作,解放双手。



    本文共计1869个文字,预计阅读时间需要8分钟。

    如何用Python高效提取PDF特定内容并生成新PDF文件?

    在众多场合,我们往往不会预知期望提取的页码,而是希望将包含指定内容的页面合并为新的PDF,并提取文本。以下以两个实际需求为例进行讲解。

    案例一:合并包含特定关键词的页面

    假设我们需要将文档中所有包含技术交流关键词的页面合并为一个PDF。

    1. 使用PDF阅读器打开文档。

    2.使用搜索功能查找技术交流。

    3.将所有搜索结果页面复制粘贴到一个新的PDF文档中。

    案例二:提取特定章节的文本

    假设我们需要从文档中提取第一章和第二章的内容。

    1. 定位到第一章的起始页。

    2.按住鼠标左键,拖动至第二章的结束页,选择整个章节内容。

    3.复制选中的内容,粘贴到文本编辑器中。

    注意:以上操作的具体步骤可能因使用的软件和设备而异。


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

    资料、代码、技术交流,文末获取

    01 需求描述

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

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


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

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


    02 前置知识和逻辑梳理

    2.1​​PyPDF2​​ 模块实现合并

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

    from PyPDF2 import PdfFileReader, PdfFileWriter

    这里导入了两个方法:

  • ​​PdfFileReader​​ 可以理解为读取器
  • ​​PdfFileWriter​​ 可以理解为写入器
  • 利用 ​​PyPDF2​​ 实现合并运用的一下逻辑:

  • 读取器将所有pdf读取一遍
  • 读取器将读取的内容交给写入器
  • 写入器统一输出到一个新pdf
  • 隐含知识点:读取器只能将读取的内容一页一页交给写入器

    2.2 获取与添加页面

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

    如何用Python高效提取PDF特定内容并生成新PDF文件?

  • ​​.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等模块实现批量操作,解放双手。