使用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_encrypted、pdfReader.pages遍历页面)。 - 安全的文件操作:用
with语句自动处理文件的打开和关闭,不用手动调用close()。 - 跨平台路径:用
os.path.join拼接路径,适配Windows、Linux等不同系统的路径分隔符。 - 异常捕获:捕获
PdfReadError,单个文件的问题不会导致整个程序崩溃。
额外排查提示
如果还是解密失败,可以试试这些方向:
- 确认输入的密码是否准确(注意大小写、特殊字符、全角半角)
- 部分PDF用了PyPDF2不支持的加密算法(比如AES-256的特殊变体),这种情况可以换
PyMuPDF(fitz)库试试,它对加密PDF的支持更全面。
内容的提问来源于stack exchange,提问作者Lukasz




