在日常工作中,我們經(jīng)常會(huì)遇到一些被加密的PDF文件。為了能夠順利地閱讀或編輯這些文件,我們需要先破解其密碼。本文將介紹如何開(kāi)發(fā)一個(gè)帶有圖形用戶(hù)界面(GUI)的PDF解密工具,可以方便地選擇文件并解密PDF文檔。
工具選擇與環(huán)境準(zhǔn)備 開(kāi)發(fā)PDF解密工具所需的環(huán)境包括Python編程語(yǔ)言及其一些庫(kù):
PyPDF2:用于讀取和寫(xiě)入PDF文件。 PyQt5:用于創(chuàng)建圖形用戶(hù)界面。 PyInstaller:用于將Python腳本打包成可執(zhí)行文件。首先,確保你已安裝所需的庫(kù),可以使用以下命令進(jìn)行安裝: pip install PyPDF2 PyQt5 pyinstaller
GUI界面的設(shè)計(jì)與實(shí)現(xiàn) 我們的工具需要一個(gè)簡(jiǎn)單的用戶(hù)界面,使用戶(hù)能夠選擇加密的PDF文件、選擇解密后的保存路徑,并顯示解密進(jìn)度。我們使用PyQt5來(lái)實(shí)現(xiàn)這個(gè)界面。
初始化界面 首先,我們創(chuàng)建一個(gè)PDFDecryptor
類(lèi),繼承自QWidget
,并在其中初始化界面元素。
import sysfrom PyPDF2 import PdfReader, PdfWriterfrom PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QFileDialog, QTextEdit, QLabelclass 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('開(kāi)始解密' ) 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)
文件選擇與路徑選擇 接下來(lái),我們實(shí)現(xiàn)文件選擇和路徑選擇功能。這兩個(gè)功能通過(guò)點(diǎn)擊按鈕來(lái)觸發(fā),并在日志區(qū)域顯示用戶(hù)的選擇。
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} ' )
解密功能的實(shí)現(xiàn) 在用戶(hù)選擇文件和保存路徑后,點(diǎn)擊“開(kāi)始解密”按鈕即可觸發(fā)解密操作。我們通過(guò)調(diào)用load_pdf
方法來(lái)讀取并解密PDF文件,然后使用PdfWriter
將解密后的內(nèi)容寫(xiě)入新的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('未能讀取內(nèi)容' ) elif not pdf_reader.is_encrypted: self.log.append('文件未加密,無(wú)需操作' ) 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('請(qǐng)先選擇PDF文件' )def load_pdf (self, file_path) : try : pdf_file = open(file_path, 'rb' ) except Exception as error: self.log.append('無(wú)法打開(kāi)文件: ' + str(error)) return None reader = PdfReader(pdf_file, strict=False ) if reader.is_encrypted: try : reader.decrypt('' ) except Exception as error: self.log.append('無(wú)法解密文件: ' + str(error)) return None return reader
運(yùn)行主程序 最后,我們?cè)谥鞒绦蛑羞\(yùn)行我們的PDF解密工具。
if __name__ == '__main__' : app = QApplication(sys.argv) ex = PDFDecryptor() ex.show() sys.exit(app.exec_())
打包成可執(zhí)行文件 為了方便用戶(hù)使用,我們可以將該P(yáng)ython腳本打包成一個(gè)可執(zhí)行文件。使用PyInstaller
可以輕松實(shí)現(xiàn)這一點(diǎn):
pyinstaller --onefile --windowed pdf解密.py
將pdf解密.py
替換為你的腳本文件名。運(yùn)行上述命令后,將在dist
文件夾中生成一個(gè)可執(zhí)行文件,可以直接運(yùn)行它來(lái)使用我們的PDF解密工具。
完整代碼分享 import sysfrom PyPDF2 import PdfReader, PdfWriterfrom PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QFileDialog, QTextEdit, QLabelclass 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('開(kāi)始解密' ) 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('未能讀取內(nèi)容' ) elif not pdf_reader.is_encrypted: self.log.append('文件未加密,無(wú)需操作' ) 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('請(qǐng)先選擇PDF文件' ) def load_pdf (self, file_path) : try : pdf_file = open(file_path, 'rb' ) except Exception as error: self.log.append('無(wú)法打開(kāi)文件: ' + str(error)) return None reader = PdfReader(pdf_file, strict=False ) if reader.is_encrypted: try : reader.decrypt('' ) except Exception as error: self.log.append('無(wú)法解密文件: ' + str(error)) return None return readerif __name__ == '__main__' : app = QApplication(sys.argv) ex = PDFDecryptor() ex.show() sys.exit(app.exec_())