2014-10-07 25 views
7

Hiện tại tôi đang sử dụng PyPDF 2 làm phụ thuộc.PyPDF 2 Giải mã không hoạt động

tôi đã gặp phải một số tập tin được mã hóa và xử lý chúng như bình thường (trong đoạn mã sau):

PDF = PdfFileReader(file(pdf_filepath, 'rb')) 
    if PDF.isEncrypted: 
     PDF.decrypt("") 
     print PDF.getNumPages() 

filepath tôi trông giống như "~/blah/FDJKL492019 21.490, LFS.pdf" PDF.decrypt ("") trả về 1, có nghĩa là nó đã thành công. Nhưng khi nó chạm vào tệp PDF.getNumPages(), nó vẫn làm tăng lỗi, "PyPDF2.utils.PdfReadError: Tệp chưa được giải mã".

Làm cách nào để loại bỏ lỗi này? Tôi có thể mở tệp PDF chỉ bằng cách nhấp đúp (mặc định mở bằng Adobe Reader).

Trả lời

5

Để trả lời câu hỏi của riêng tôi: Nếu bạn có bất kỳ khoảng trống nào trong tên tệp của bạn, thì chức năng giải mã PyPDF 2 cuối cùng sẽ không thành công mặc dù trả về mã thành công. Cố gắng bám vào dấu gạch dưới khi đặt tên tệp PDF của bạn trước khi bạn chạy chúng thông qua PyPDF2.

Ví dụ,

Thay vì "FDJKL492019 21.490, LFS.pdf" làm điều gì đó như "FDJKL492019_21490_, LFS.pdf".

+0

Cũng được phát hiện! Nó phải là một hạn chế của Python hoặc đặc biệt là thư viện cụ thể này (nó không có gì để làm với định dạng PDF). Bạn có thể muốn đề cập đến điều này trên trang web từ nơi bạn nhận được nó. – usr2564301

+0

Dường như nó cũng không thành công khi sử dụng các ký tự đặc biệt "®ø" vv .. – rsm

6

Lỗi này có thể xảy ra do mã hóa AES 128-bit trên pdf, xem https://github.com/mstamy2/PyPDF2/issues/53

Một workaround là để giải mã tất cả các file PDF isEncrypted với "qpdf"

qpdf --password='' --decrypt input.pdf output.pdf 

Thậm chí nếu PDF của bạn không không xuất hiện mật khẩu được bảo vệ, nó vẫn có thể được mã hóa mà không có mật khẩu. Đoạn mã trên giả định đây là trường hợp.

0

Không có gì liên quan đến việc tệp đã được giải mã hay chưa khi sử dụng phương thức getNumPages().

Nếu chúng ta hãy nhìn vào mã nguồn của getNumPages():

def getNumPages(self): 
    """ 
    Calculates the number of pages in this PDF file. 

    :return: number of pages 
    :rtype: int 
    :raises PdfReadError: if file is encrypted and restrictions prevent 
     this action. 
    """ 

    # Flattened pages will not work on an Encrypted PDF; 
    # the PDF file's page count is used in this case. Otherwise, 
    # the original method (flattened page count) is used. 
    if self.isEncrypted: 
     try: 
      self._override_encryption = True 
      self.decrypt('') 
      return self.trailer["/Root"]["/Pages"]["/Count"] 
     except: 
      raise utils.PdfReadError("File has not been decrypted") 
     finally: 
      self._override_encryption = False 
    else: 
     if self.flattenedPages == None: 
      self._flatten() 
     return len(self.flattenedPages) 

chúng ta sẽ nhận thấy rằng nó là self.isEncrypted sở hữu kiểm soát dòng chảy. Và như chúng ta đều biết thuộc tính isEncrypted là chỉ đọc và không thể thay đổi ngay cả khi pdf được giải mã.

Vì vậy, cách dễ dàng để xử lý tình trạng này là chỉ cần thêm mật khẩu như là đối số-từ khóa với chuỗi rỗng như giá trị mặc định và vượt qua mật khẩu của bạn khi sử dụng getNumPages() phương pháp và bất kỳ phương pháp nào khác xây dựng vượt ra ngoài nó

1

Các mã sau đây có thể giải quyết vấn đề này:

import os 
import PyPDF2 
from PyPDF2 import PdfFileReader 

fp = open(filename) 
pdfFile = PdfFileReader(fp) 
if pdfFile.isEncrypted: 
    try: 
     pdfFile.decrypt('') 
     print('File Decrypted (PyPDF2)') 
    except: 
     command = ("cp "+ filename + 
      " temp.pdf; qpdf --password='' --decrypt temp.pdf " + filename 
      + "; rm temp.pdf") 
     os.system(command) 
     print('File Decrypted (qpdf)') 
     fp = open(filename) 
     pdfFile = PdfFileReader(fp) 
else: 
    print('File Not Encrypted') 
Các vấn đề liên quan