You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用PyPDF2批量解密PDF时报错:File has not been decrypted 求解决方案

解决PyPDF2解密PDF时的File has not been decrypted错误

这个报错大概率是因为解密操作没成功就急着读取PDF内容——要么是密码不对,要么代码里没判断解密状态就直接处理页面了。咱们一步步来修复:

错误原因拆解

你当前的代码调用pdfReader.decrypt(passwd)后,没检查解密是否成功。在旧版PyPDF2的PdfFileReader里,decrypt()会返回一个整数:

  • 0:解密失败(密码错误或不支持的加密方式)
  • 1:用用户密码解密成功
  • 2:用所有者密码解密成功

如果返回0,PDF还是加密状态,这时候去调用numPages或者getPage(),自然会触发PdfReadError。另外,PdfFileReader已经被官方弃用,推荐用新版的PdfReader类,API更稳定简洁。

修复后的代码

我给你的代码做了几处关键调整:

import os
import PyPDF2
from PyPDF2.errors import PdfReadError

passwd = input("Password to decrypt: ")
pdf_folder = "pdfy"

# 遍历目标文件夹里的PDF文件
for filename in os.listdir(pdf_folder):
    # 兼容大写后缀的PDF文件
    if filename.lower().endswith('.pdf'):
        file_path = os.path.join(pdf_folder, filename)  # 用os.path.join避免路径分隔符问题
        try:
            # 用with语句自动管理文件开闭,避免资源泄漏
            with open(file_path, 'rb') as pdfFile:
                # 替换弃用的PdfFileReader为新版PdfReader
                pdfReader = PyPDF2.PdfReader(pdfFile)
                pdfWriter = PyPDF2.PdfWriter()

                if pdfReader.is_encrypted:  # 新版属性是is_encrypted,替代旧版isEncrypted
                    # 新版decrypt返回布尔值:True成功,False失败
                    decrypt_success = pdfReader.decrypt(passwd)
                    if not decrypt_success:
                        print(f"密码错误,无法解密文件:{filename}")
                        continue

                    # 解密成功后,批量复制页面到writer
                    for page in pdfReader.pages:
                        pdfWriter.add_page(page)

                    # 生成解密后的文件名
                    name_part, ext_part = os.path.splitext(filename)
                    output_filename = f"{name_part}_decrypted{ext_part}"
                    output_path = os.path.join(pdf_folder, output_filename)

                    with open(output_path, 'wb') as pdfOutputFile:
                        pdfWriter.write(pdfOutputFile)
                    print(f"已完成解密并保存:{output_filename}")
                else:
                    print(f"{filename} 未加密,跳过处理")
        except PdfReadError as e:
            print(f"处理文件 {filename} 时出错:{str(e)}")

核心修改点

  • 校验解密结果:添加对decrypt()返回值的判断,失败时直接跳过并提示,避免程序报错中断。
  • 升级API版本:用新版PdfReader替代弃用的PdfFileReader,同步更新了属性和方法(比如is_encryptedpdfReader.pages遍历页面)。
  • 安全的文件操作:用with语句自动处理文件的打开和关闭,不用手动调用close()
  • 跨平台路径:用os.path.join拼接路径,适配Windows、Linux等不同系统的路径分隔符。
  • 异常捕获:捕获PdfReadError,单个文件的问题不会导致整个程序崩溃。

额外排查提示

如果还是解密失败,可以试试这些方向:

  • 确认输入的密码是否准确(注意大小写、特殊字符、全角半角)
  • 部分PDF用了PyPDF2不支持的加密算法(比如AES-256的特殊变体),这种情况可以换PyMuPDF(fitz)库试试,它对加密PDF的支持更全面。

内容的提问来源于stack exchange,提问作者Lukasz

火山引擎 最新活动