前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PDF文件批量去除密码

PDF文件批量去除密码

原创
作者头像
IT蜗壳-Tango
修改2024-05-17 11:19:21
12200
代码可运行
修改2024-05-17 11:19:21
举报
运行总次数:0
代码可运行

本文只讨论技术实现。请大家尊重版权,拒绝盗版。

背景

PDF加密是一种保护PDF文档内容的技术,通过密码或权限设置来控制对文档的访问和操作。PDF加密主要有两种类型:用户密码和所有者密码。

  1. 用户密码(User Password):需要在打开PDF文档时输入的密码。如果没有这个密码,文档将无法打开和查看。
  2. 所有者密码(Owner Password):用于控制文档的权限,比如打印、复制文本和图像、编辑文档等。这种密码可以让用户打开和查看文档,但限制其他操作。

PDF加密的实现

在不同的平台和工具上,可以通过多种方式实现PDF加密。以下是几种常见的方法:

使用Adobe Acrobat

Adobe Acrobat是一个流行的PDF处理工具,可以轻松地加密PDF文档:

  1. 打开Adobe Acrobat并加载你要加密的PDF文件。
  2. 选择“文件” > “保护” > “使用密码加密”。
  3. 在弹出的对话框中,设置用户密码和/或所有者密码。
  4. 选择要应用的权限(如是否允许打印或编辑文档)。
  5. 点击“确定”保存设置,然后保存加密后的PDF文件。

最近在备考架构师,在网上得到了一些资料,奈何这些PDF文件是有密码保护的,每次打开都要输入密码很不方便,尤其是在手机上用微信读书打开时。

于是就有了今天的话题,我们能不能把这些密码自动去掉方便我们的查看与学习。

我这种情况是预先知道了打开的密码,不涉及到暴力破解的问题。

技术依赖

我们主要使用Python的PyPDF2这个库的decrypt方法来去除密码。

实现思路

我们的目录大致如下图所示

这里每个文件夹都有若干个PDF文件,我们希望它能自动把每个PDF都去除密码,因此需要我们先能遍历出所有的PDF文件并使用PyPDF2的decrypt这个方法将密码移除,将移除后的PDF字节流保存为一个新的文件。

开始编码

首先,确保你已经安装了 PyPDF2 库。如果没有安装,可以使用 pip 进行安装:

代码语言:bash
复制
pip install PyPDF2
pip install pycryptodome

我们先写一个获取指定目录下所有的PDF文件的脚本,包括子目录下的。

如果你想要包括目录下所有子目录中的 PDF 文件,你可以在 os.walk 函数中设置 topdown 参数为 True。这样可以确保在遍历子目录时,仍然能够遍历子目录中的所有文件

代码语言:python
代码运行次数:0
复制
import os

def get_pdf_files(directory):
    pdf_files = []
    # 遍历目录及其子目录中的所有文件
    for root, dirs, files in os.walk(directory, topdown=True):
        for file in files:
            # 检查文件是否以 .pdf 结尾
            if file.lower().endswith('.pdf'):
                # 如果是 PDF 文件,则将其路径添加到列表中
                pdf_files.append(os.path.join(root, file))
    return pdf_files

# 示例用法:
directory = '/path/to/directory'  # 替换为你要搜索的目录的路径
pdf_files = get_pdf_files(directory)
print("PDF 文件列表:")
for pdf_file in pdf_files:
    print(pdf_file)

在获取完所有的PDF文件后,我开始最主要的工作,以下代码演示了如何打开一个有密码保护的 PDF 文件,输入密码解锁并保存为一个没有密码的新文件。

具体代码如下:

代码语言:python
代码运行次数:0
复制
import PyPDF2

def remove_pdf_password(input_pdf, output_pdf, password):
    with open(input_pdf, 'rb') as input_file:
        pdf_reader = PyPDF2.PdfReader(input_file)
        
        # 判断PDF文件是否加密
        if pdf_reader.is_encrypted:
            pdf_reader.decrypt(password)
        
        # 创建一个新的PDF对象
        pdf_writer = PyPDF2.PdfWriter()
        
        # 将去除密码后的每页PDF添加到pdf_writer这个对象中
        for page_num in range(len(pdf_reader.pages)):
            pdf_writer.add_page(pdf_reader.pages[page_num])
        
        # 另存为新文件
        with open(output_pdf, 'wb') as output_file:
            pdf_writer.write(output_file)

input_file = 'encrypted.pdf'
output_file = 'decrypted.pdf'
password = 'your_password_here'

remove_pdf_password(input_file, output_file, password)

两个主要功能都实现之后,我们将两个脚本合并一下。合并后的完整代码如下:

代码语言:python
代码运行次数:0
复制
import os
import PyPDF2

def get_pdf_files(directory):
    pdf_files = []
    # 遍历目录及其子目录中的所有文件
    for root, dirs, files in os.walk(directory, topdown=True):
        for file in files:
            # 检查文件是否以 .pdf 结尾
            if file.lower().endswith('.pdf'):
                # 如果是 PDF 文件,则将其路径添加到列表中
                pdf_files.append(os.path.join(root, file))
    return pdf_files

def remove_pdf_password(input_pdf, output_pdf, password):
    with open(input_pdf, 'rb') as input_file:
        pdf_reader = PyPDF2.PdfReader(input_file)
        
        # 判断PDF文件是否加密
        if pdf_reader.is_encrypted:
            pdf_reader.decrypt(password)
        
        # 创建一个新的PDF对象
        pdf_writer = PyPDF2.PdfWriter()
        
        # 将去除密码后的每页PDF添加到pdf_writer这个对象中
        for page_num in range(len(pdf_reader.pages)):
            pdf_writer.add_page(pdf_reader.pages[page_num])
        
        # 另存为新文件
        with open(output_pdf, 'wb') as output_file:
            pdf_writer.write(output_file)

def main():
    directory = '/path/to/directory'  # 替换为你要搜索的目录的路径
    pdf_files = get_pdf_files(directory)    
    for pdf_file in pdf_files:
        output_file = pdf_file.replace('.pdf', '_new.pdf')
        password = 'xxxxxxx'  # 替换为PDF文件的密码
        remove_pdf_password(pdf_file, output_file, password)
        print(f"output_file: {output_file}")

if __name__ == "__main__":
    main()

最后

上面的代码只是一个demo,还有很多需要优化的地方,例如文件破损的异常判断,多密码的情况等。

好了,今天的内容就是这些,希望对你有所帮助,我们下期见。


我正在参与2024腾讯技术创作特训营最新征文,快来和我瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
    • PDF加密的实现
      • 使用Adobe Acrobat
  • 技术依赖
  • 实现思路
  • 开始编码
  • 最后
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档