Python PyPDF2、pdfplumber 提取 PDF 文本、图片内容

Python PyPDF2、pdfplumber 提取 PDF 文本、图片内容PythonPyPDF2、pdfplumber提取PDF文本、图片内容PythonPyPDF2、pdfplumber提取PDF文本、图片内容安装库安装pdfplumber安装PyPDF2内容提取代码图片提取文本提取完整代码PythonPyPDF2、pdfplumber提取PDF文本、图片内容说明本方法提取的图片并不算完整,我测试用的是阿里2017年双十一的一份P…

大家好,又见面了,我是你们的朋友全栈君。

Python PyPDF2、pdfplumber 提取 PDF 文本、图片内容

说明

本方法提取的图片并不算完整,我测试用的是阿里2017年双十一的一份PDF,AliDouble11.pdf,提取过程中有一处报错,部分图片提取不完整

由于PyPDF2 直接提取文本内容对中文支持不友好,因此结合两个库提取

安装库

安装 pdfplumber

pdfplumber 可以使用 pip 安装

pip install pdfplumber 

安装 PyPDF2

PyPDF2 需要去 GitHub 下载 https://github.com/mstamy2/PyPDF2

下载完成后解压,进入解压的目录 E:\tools\PyPDF2-master

执行 setup.py 进行安装

python setup.py install

不用pip安装的原因是 pip 下载的只更新到 1.26.0 更新日期是 2016年5月19日,只用这个版本无法提取 jpg 格式图片,会报错

Traceback (most recent call last):
  File "D:/projects/util/pdf_util.py", line 106, in extract_image
    data = xObject[obj].getData()
  File "D:\projects\util\venv\lib\site-packages\PyPDF2\generic.py", line 844, in getData
    decoded._data = filters.decodeStreamData(self)
  File "D:\projects\util\venv\lib\site-packages\PyPDF2\filters.py", line 361, in decodeStreamData
    raise NotImplementedError("unsupported filter %s" % filterType)
NotImplementedError: unsupported filter /DCTDecode

如果已安装 pypdf 建议先卸载 然后安装,卸载的时候最好检查是否卸载完全,即 PyPDF2 文件夹是否仍存在 ,否则可能会报错

ImportError: cannot import name 'paethPredictor'

内容提取代码

图片提取

示例代码在文件夹 PyPDF2-master\Scripts 下的 pdf-image-extractor.py

import time

import PyPDF2
import pdfplumber
from PIL import Image


def extract_image(page):
    try:
        # 提取第2页图片(从0开始计数)
        page_image = pdf_image_reader.getPage(pageNumber=1)
        extract_image(page_image)
        if '/XObject' in page['/Resources']:
            xObject = page['/Resources']['/XObject'].getObject()
            for obj in xObject:
                if xObject[obj]['/Subtype'] == '/Image':
                    size = (xObject[obj]['/Width'], xObject[obj]['/Height'])
                    data = xObject[obj].getData()
                    if xObject[obj]['/ColorSpace'] == '/DeviceRGB':
                        mode = "RGB"
                    else:
                        mode = "P"
                    # 保存图片的文件名前缀
                    img_pre = str(int(time.time()*1000))
                    if '/Filter' in xObject[obj]:
                        if xObject[obj]['/Filter'] == '/FlateDecode':
                            img = Image.frombytes(mode, size, data)
                            img.save(img_pre + ".png")
                        elif xObject[obj]['/Filter'] == '/DCTDecode':
                            img = open(img_pre + ".jpg", "wb")
                            img.write(data)
                            img.close()
                        elif xObject[obj]['/Filter'] == '/JPXDecode':
                            img = open(img_pre + ".jp2", "wb")
                            img.write(data)
                            img.close()
                        elif xObject[obj]['/Filter'] == '/CCITTFaxDecode':
                            img = open(img_pre + ".tiff", "wb")
                            img.write(data)
                            img.close()
                    else:
                        img = Image.frombytes(mode, size, data)
                        img.save(img_pre + ".png")
        else:
            print("本页无图片")
    except:
        print("图片提取失败")

文本提取

def extract_content(pdf_path):
    # 内容提取,使用 pdfplumber 打开 PDF,用于提取文本
    with pdfplumber.open(pdf_path) as pdf_file:
        # 使用 PyPDF2 打开 PDF 用于提取图片
        pdf_image_reader = PyPDF2.PdfFileReader(open(pdf_path, "rb"))
        print(pdf_image_reader.getNumPages())

        content = ''
        # len(pdf.pages)为PDF文档页数,一页页解析
        for i in range(len(pdf_file.pages)):
            print("当前第 %s 页" % i)
            # pdf.pages[i] 是读取PDF文档第i+1页
            page_text = pdf_file.pages[i]
            # page.extract_text()函数即读取文本内容
            page_content = page_text.extract_text()
            if page_content:
                content = content + page_content + "\n"
                print(page_content)

完整代码

import time

import PyPDF2
import pdfplumber
from PIL import Image


def extract_image(page):
    try:
        if '/XObject' in page['/Resources']:
            xObject = page['/Resources']['/XObject'].getObject()
            for obj in xObject:
                if xObject[obj]['/Subtype'] == '/Image':
                    size = (xObject[obj]['/Width'], xObject[obj]['/Height'])
                    data = xObject[obj].getData()
                    if xObject[obj]['/ColorSpace'] == '/DeviceRGB':
                        mode = "RGB"
                    else:
                        mode = "P"
                    # 保存图片的文件名前缀
                    img_pre = str(int(time.time()*1000))
                    if '/Filter' in xObject[obj]:
                        if xObject[obj]['/Filter'] == '/FlateDecode':
                            img = Image.frombytes(mode, size, data)
                            img.save(img_pre + ".png")
                        elif xObject[obj]['/Filter'] == '/DCTDecode':
                            img = open(img_pre + ".jpg", "wb")
                            img.write(data)
                            img.close()
                        elif xObject[obj]['/Filter'] == '/JPXDecode':
                            img = open(img_pre + ".jp2", "wb")
                            img.write(data)
                            img.close()
                        elif xObject[obj]['/Filter'] == '/CCITTFaxDecode':
                            img = open(img_pre + ".tiff", "wb")
                            img.write(data)
                            img.close()
                    else:
                        img = Image.frombytes(mode, size, data)
                        img.save(img_pre + ".png")
        else:
            print("本页无图片")
    except:
        print("图片提取失败")


def extract_content(pdf_path):
    # 内容提取,使用 pdfplumber 打开 PDF,用于提取文本
    with pdfplumber.open(pdf_path) as pdf_file:
        # 使用 PyPDF2 打开 PDF 用于提取图片
        pdf_image_reader = PyPDF2.PdfFileReader(open(pdf_path, "rb"))
        print(pdf_image_reader.getNumPages())

        content = ''
        # len(pdf.pages)为PDF文档页数,一页页解析
        for i in range(len(pdf_file.pages)):
            print("当前第 %s 页" % i)
            # pdf.pages[i] 是读取PDF文档第i+1页
            page_text = pdf_file.pages[i]
            # page.extract_text()函数即读取文本内容
            page_content = page_text.extract_text()
            if page_content:
                content = content + page_content + "\n"
                print(page_content)

            # 提取图片
            page_image = pdf_image_reader.getPage(pageNumber=i)
            extract_image(page_image)


if __name__ == '__main__':
    pdf_file = "../media/AliDouble11.pdf"
    extract_content(pdf_file)
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/152390.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 实时 摔倒识别 /运动分析/打架等异常行为识别/控制手势识别等所有行为识别全家桶 原理 + 代码 + 数据+ 模型 开源!「建议收藏」

    实时 摔倒识别 /运动分析/打架等异常行为识别/控制手势识别等所有行为识别全家桶 原理 + 代码 + 数据+ 模型 开源!「建议收藏」文章目录一、基本过程和思想二、视频理解还有哪些优秀框架三、效果体验~使用手势:pythonrun_gesture_recognition.py健身_跟踪器:卡路里计算三、训练自己数据集步骤然后,打开这个网址:点击一下startnewproject但是官方的制作方法是有着严重bug的~我们该怎么做呢!原代码解读大家好,我是cv君,很多大创,比赛,项目,工程,科研,学术的炼丹术士问我上述这些识别,该怎么做,怎么选择框架,今天可以和大家分析一下一些方案:用单帧目标检测做的话,前后语义相关性很差(也有

    2022年6月21日
    54
  • Navicat MySQL 激活码【中文破解版】

    (Navicat MySQL 激活码)2021最新分享一个能用的的激活码出来,希望能帮到需要激活的朋友。目前这个是能用的,但是用的人多了之后也会失效,会不定时更新的,大家持续关注此网站~IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.html…

    2022年3月28日
    56
  • kubernetes可以实现容器集群的哪些功能_hadoop高可用集群搭建

    kubernetes可以实现容器集群的哪些功能_hadoop高可用集群搭建二进制方式部署Kubernetes高可用集群文章目录二进制方式部署Kubernetes高可用集群1.环境准备1.1.Kubernetes高可用集群部署方式1.2.Kubernetes集群弃用docker容器1.3.Kubernetes集群所需的证书1.4.环境准备1.5.安装cfssl证书生成工具2.操作系统初始化配置3.部署Etcd集群3.1.使用cfssl证书工具生成etcd证书3.2.部署etcd集群4.部署Docker服务4.1.安装docker4.2.为docker创建systemctl启动脚本

    2025年8月28日
    6
  • bzero和memset哪个更耗时_malloc_trim

    bzero和memset哪个更耗时_malloc_trim 关于字符数组的初始化,在项目的压力测试中,发现性能明显下降,变怀疑在程序中的若干临时字符数组的初始化(使用bzero)身上。于是修改为首个字符置零的方式而非全部置零的方式初始化,响应得到明显的提升。原来在mp3检索的每一条结果都要进行bzero对临时数组初始化,每一个请求需要30次的bzero对临时数组的置零。于是想到了,在非必要的情况下,只对临时数组的第一个(或前几个)字符置零的初始化

    2022年10月10日
    4
  • PriorityQueue源码分析

    PriorityQueue源码分析来源:Java编程的逻辑1前导将新的头部与两个孩子节点中较小的比较,如果不大于该孩子节点,则满足堆的性质,结束,否则与较小的孩子进行交换,交换后,再与较小的孩子比较和交换,一直到没有孩子,或者不大于两个孩子节点。这个过程我们般称为siftdown与父节点比较,如果大于等于父节点,则满足堆的性质,结束,否则与父节点进行交换,然后再与父节点比较和交换,直到父节点为空或者大于等于父节点;称之为…

    2022年6月8日
    32
  • html怎么将表格居中_HTML居中代码

    html怎么将表格居中_HTML居中代码表格是一种以有组织的方式呈现大量信息的绝佳方式。销售数据、网页流量、股票市场趋势和学生成绩是经常以表格形式呈现的信息示例。使用HTML将表格添加到网页时,将其置于页面中心可能更具视觉吸引力。居中文本和图片通常是通过text-align类或通过CSS来完成的,但是居中表格需要不同的方法。下面提供了有关如何使表格在网页上居中的详细信息。将表格添加到网页时,默认情况下,它与页面或容器的左侧对齐,如下所示。上表的HTML源代码如下。要使此表居中,您需要添加;margin-left:auto;margin-r

    2026年1月21日
    7

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号