PyPDF 2 не работает

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

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

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

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

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

Ответ 1

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

Например,

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

Ответ 2

Эта ошибка может возникать из-за 128-битного шифрования AES в pdf, см. Запрос - есть ли способ обойти ограничения безопасности для pdf?

Один из обходных путей - расшифровать все файлы isEncrypted с помощью qpdf.

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

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

Ответ 3

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

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

Ответ 4

Это не имеет никакого отношения к тому, был ли файл расшифрован или нет при использовании метода 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 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() и любого другого метода, построенного за его пределами

Ответ 5

Вы можете попробовать пакет PyMuPDF, он может открывать зашифрованные файлы и решать мои проблемы.

Ссылка: Документация PyMuPDF