PyPDF 2 Decrypt Not Working

瘦欲@ 提交于 2019-11-29 06:14:22

This error may come about due to 128-bit AES encryption on the pdf, see https://github.com/mstamy2/PyPDF2/issues/53

One workaround is to decrypt all isEncrypted pdfs with "qpdf"

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

Even if your PDF does not appear password protected, it may still be encrypted with no password. The above snippet assumes this is the case.

To Answer My Own Question: If you have ANY spaces in your file name, then PyPDF 2 decrypt function will ultimately fail despite returning a success code. Try to stick to underscores when naming your PDFs before you run them through PyPDF2.

For example,

Rather than "FDJKL492019 21490 ,LFS.pdf" do something like "FDJKL492019_21490_,LFS.pdf".

The following code could solve this problem:

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

It has nothing to do with whether the file has been decrypted or not when using the method getNumPages().

If we take a look at the source code of 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)

we will notice that it is the self.isEncrypted property controlling the flow. And as we all know the isEncrypted property is read-only and not changeable even when the pdf is decrypted.

So, the easy way to handle the situation is just add the password as key-word argument with empty string as default value and pass your password when using the getNumPages() method and any other method build beyond it

You can try PyMuPDF package, it can open encrypted files and solved my problems.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!