編程學習網 > 編程語言 > Python > python輕松實現PDF解密,含GUI及打包技巧
2024
07-10

python輕松實現PDF解密,含GUI及打包技巧


在日常工作中,我們經常會遇到一些被加密的PDF文件。為了能夠順利地閱讀或編輯這些文件,我們需要先破解其密碼。本文將介紹如何開發一個帶有圖形用戶界面(GUI)的PDF解密工具,可以方便地選擇文件并解密PDF文檔。


工具選擇與環境準備
開發PDF解密工具所需的環境包括Python編程語言及其一些庫:

PyPDF2:用于讀取和寫入PDF文件。
PyQt5:用于創建圖形用戶界面。
PyInstaller:用于將Python腳本打包成可執行文件。首先,確保你已安裝所需的庫,可以使用以下命令進行安裝:
pip install PyPDF2 PyQt5 pyinstaller
GUI界面的設計與實現
我們的工具需要一個簡單的用戶界面,使用戶能夠選擇加密的PDF文件、選擇解密后的保存路徑,并顯示解密進度。我們使用PyQt5來實現這個界面。

初始化界面
首先,我們創建一個PDFDecryptor類,繼承自QWidget,并在其中初始化界面元素。

import sys
from PyPDF2 import PdfReader, PdfWriter
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QFileDialog, QTextEdit, QLabel

class PDFDecryptor(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()
        
    def initUI(self):
        self.setWindowTitle('PDF解密工具')
        self.setGeometry(100, 100, 600, 400)
        
        layout = QVBoxLayout()
        
        self.file_label = QLabel('選擇加密的PDF文件:')
        layout.addWidget(self.file_label)
        
        self.file_button = QPushButton('選擇文件')
        self.file_button.clicked.connect(self.select_file)
        layout.addWidget(self.file_button)
        
        self.output_label = QLabel('選擇解密后的PDF文件保存路徑:')
        layout.addWidget(self.output_label)
        
        self.output_button = QPushButton('選擇路徑')
        self.output_button.clicked.connect(self.select_output_path)
        layout.addWidget(self.output_button)
        
        self.decrypt_button = QPushButton('開始解密')
        self.decrypt_button.clicked.connect(self.decrypt_pdf)
        layout.addWidget(self.decrypt_button)
        
        self.log = QTextEdit()
        self.log.setReadOnly(True)
        layout.addWidget(self.log)
        
        self.setLayout(layout)
文件選擇與路徑選擇
接下來,我們實現文件選擇和路徑選擇功能。這兩個功能通過點擊按鈕來觸發,并在日志區域顯示用戶的選擇。

def select_file(self):
    options = QFileDialog.Options()
    file_path, _ = QFileDialog.getOpenFileName(self, "選擇加密的PDF文件", "", "PDF Files (*.pdf)", options=options)
    if file_path:
        self.file_path = file_path
        self.log.append(f'選擇的文件: {file_path}')

def select_output_path(self):
    options = QFileDialog.Options()
    folder_path = QFileDialog.getExistingDirectory(self, "選擇解密后的PDF文件保存路徑", options=options)
    if folder_path:
        self.output_path = folder_path
        self.log.append(f'保存路徑: {folder_path}')
解密功能的實現
在用戶選擇文件和保存路徑后,點擊“開始解密”按鈕即可觸發解密操作。我們通過調用load_pdf方法來讀取并解密PDF文件,然后使用PdfWriter將解密后的內容寫入新的PDF文件。

def decrypt_pdf(self):
    if hasattr(self, 'file_path'):
        input_path = self.file_path
        
        if not hasattr(self, 'output_path'):
            output_path = "".join(input_path.split('.')[:-1]) + '_decrypted.pdf'
        else:
            output_path = f"{self.output_path}/{input_path.split('/')[-1].split('.')[0]}_decrypted.pdf"
        
        self.log.append('正在解密...')
        pdf_reader = self.load_pdf(input_path)
        if pdf_reader is None:
            self.log.append("未能讀取內容")
        elif not pdf_reader.is_encrypted:
            self.log.append('文件未加密,無需操作')
        else:
            pdf_writer = PdfWriter()
            pdf_writer.append_pages_from_reader(pdf_reader)
            
            with open(output_path, 'wb') as output_file:
                pdf_writer.write(output_file)
            self.log.append(f"解密文件已生成: {output_path}")
    else:
        self.log.append("請先選擇PDF文件")

def load_pdf(self, file_path):
    try:
        pdf_file = open(file_path, 'rb')
    except Exception as error:
        self.log.append('無法打開文件: ' + str(error))
        return None

    reader = PdfReader(pdf_file, strict=False)

    if reader.is_encrypted:
        try:
            reader.decrypt('')
        except Exception as error:
            self.log.append('無法解密文件: ' + str(error))
            return None
    return reader
運行主程序
最后,我們在主程序中運行我們的PDF解密工具。

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = PDFDecryptor()
    ex.show()
    sys.exit(app.exec_())
打包成可執行文件
為了方便用戶使用,我們可以將該Python腳本打包成一個可執行文件。使用PyInstaller可以輕松實現這一點:

pyinstaller --onefile --windowed pdf解密.py
將pdf解密.py替換為你的腳本文件名。運行上述命令后,將在dist文件夾中生成一個可執行文件,可以直接運行它來使用我們的PDF解密工具。

完整代碼分享
import sys
from PyPDF2 import PdfReader, PdfWriter
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QFileDialog, QTextEdit, QLabel

class PDFDecryptor(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()
        
    def initUI(self):
        self.setWindowTitle('PDF解密工具')
        self.setGeometry(100, 100, 600, 400)
        
        layout = QVBoxLayout()
        
        self.file_label = QLabel('選擇加密的PDF文件:')
        layout.addWidget(self.file_label)
        
        self.file_button = QPushButton('選擇文件')
        self.file_button.clicked.connect(self.select_file)
        layout.addWidget(self.file_button)
        
        self.output_label = QLabel('選擇解密后的PDF文件保存路徑:')
        layout.addWidget(self.output_label)
        
        self.output_button = QPushButton('選擇路徑')
        self.output_button.clicked.connect(self.select_output_path)
        layout.addWidget(self.output_button)
        
        self.decrypt_button = QPushButton('開始解密')
        self.decrypt_button.clicked.connect(self.decrypt_pdf)
        layout.addWidget(self.decrypt_button)
        
        self.log = QTextEdit()
        self.log.setReadOnly(True)
        layout.addWidget(self.log)
        
        self.setLayout(layout)

    def select_file(self):
        options = QFileDialog.Options()
        file_path, _ = QFileDialog.getOpenFileName(self, "選擇加密的PDF文件", "", "PDF Files (*.pdf)", options=options)
        if file_path:
            self.file_path = file_path
            self.log.append(f'選擇的文件: {file_path}')

    def select_output_path(self):
        options = QFileDialog.Options()
        folder_path = QFileDialog.getExistingDirectory(self, "選擇解密后的PDF文件保存路徑", options=options)
        if folder_path:
            self.output_path = folder_path
            self.log.append(f'保存路徑: {folder_path}')

    def decrypt_pdf(self):
        if hasattr(self, 'file_path'):
            input_path = self.file_path
            
            if not hasattr(self, 'output_path'):
                output_path = "".join(input_path.split('.')[:-1]) + '_decrypted.pdf'
            else:
                output_path = f"{self.output_path}/{input_path.split('/')[-1].split('.')[0]}_decrypted.pdf"
            
            self.log.append('正在解密...')
            pdf_reader = self.load_pdf(input_path)
            if pdf_reader is None:
                self.log.append("未能讀取內容")
            elif not pdf_reader.is_encrypted:
                self.log.append('文件未加密,無需操作')
            else:
                pdf_writer = PdfWriter()
                pdf_writer.append_pages_from_reader(pdf_reader)
                
                with open(output_path, 'wb') as output_file:
                    pdf_writer.write(output_file)
                self.log.append(f"解密文件已生成: {output_path}")
        else:
            self.log.append("請先選擇PDF文件")
    
    def load_pdf(self, file_path):
        try:
            pdf_file = open(file_path, 'rb')
        except Exception as error:
            self.log.append('無法打開文件: ' + str(error))
            return None

        reader = PdfReader(pdf_file, strict=False)

        if reader.is_encrypted:
            try:
                reader.decrypt('')
            except Exception as error:
                self.log.append('無法解密文件: ' + str(error))
                return None
        return reader

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = PDFDecryptor()
    ex.show()

    sys.exit(app.exec_())

以上就是python輕松實現PDF解密,含GUI及打包技巧的詳細內容,想要了解更多Python教程歡迎持續關注編程學習網。

掃碼二維碼 獲取免費視頻學習資料

Python編程學習

查 看2022高級編程視頻教程免費獲取