2014-10-07 2 views
7

В настоящее время я использую PyPDF 2 как зависимость.PyPDF 2 Decrypt Not Working

я столкнулся с некоторыми зашифрованными файлами и обрабатывается их, как обычно (в следующем коде):

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

Моей путь_к_файлу выглядит что-то вроде «~/л/FDJKL492019 21490, LFS.pdf» PDF.decrypt ("") возвращает 1, что означает, что он был успешным. Но когда он попадает в печать PDF.getNumPages(), , он по-прежнему вызывает ошибку: «PyPDF2.utils.PdfReadError: файл не был расшифрован».

Как избавиться от этой ошибки? Я могу открыть PDF-файл с помощью двойного щелчка (который по умолчанию открывается с помощью Adobe Reader).

ответ

5

Ответьте на мой вопрос: Если у вас есть ЛЮБЫЕ пробелы в имени вашего файла, тогда функция расшифровки файла PyPDF 2 в конечном счете не удастся, несмотря на возвращение кода успеха. Попытайтесь придерживаться подчеркивания при наименовании ваших PDF-файлов, прежде чем запускать их через PyPDF2.

Например,

Вместо "FDJKL492019 21490, LFS.pdf" сделать что-то вроде "FDJKL492019_21490_, LFS.pdf".

+0

Хорошо заметили! Это должно быть ограничение Python или этой конкретной библиотеки в частности (это не имеет никакого отношения к формату PDF). Вы можете упомянуть об этом на сайте, откуда вы его получили. – usr2564301

+0

Кажется, что он также терпит неудачу при использовании специальных символов «®» и т. Д. – rsm

6

Эта ошибка может произойти из-за 128-битного AES шифрования на PDF см https://github.com/mstamy2/PyPDF2/issues/53

Один из способов заключается расшифровать все файлы PDF IsEncrypted с «qpdf»

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

Даже если ваш PDF делает не отображается защищенный паролем, он все равно может быть зашифрован без пароля. Вышеприведенный фрагмент предполагает, что это так.

0

Это не имеет никакого отношения к тому, был ли файл дешифрован или нет при использовании метода getNumPages().

Если мы посмотрим на исходный код 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) 

мы замечаем, что это свойство self.isEncrypted управления потоком. И поскольку все мы знаем, что свойство isEncrypted доступно только для чтения и не изменяется, даже когда PDF расшифровывается.

Таким образом, простой способ справиться с ситуацией просто добавить пароль в качестве ключевого слова аргумента с пустой строкой в ​​качестве значения по умолчанию и передать свой пароль при использовании метода getNumPages() и любой другой способа построить за его пределы

1

следующий код может решить эту проблему:

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')