2014-10-07 100 views
7

目前我使用PyPDF 2作爲依賴項。PyPDF 2解密不工作

我遇到了一些加密的文件和辦理 他們,你通常會(在下面的代碼):

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解密函數最終會失敗。 在通過PyPDF2運行PDF文件之前,嘗試堅持強調下劃線。

例如,

,而不是 「FDJKL492019 21490,LFS.pdf」 像做 「FDJKL492019_21490_,LFS.pdf」。

+0

看起來很棒!它必須是Python的限制或特定的庫(它與PDF格式無關)。你可能想在你的網站上提到這一點。 – usr2564301 2014-10-07 20:03:36

+0

使用「ø」等特殊字符似乎也失敗了。 – rsm 2015-07-03 17:19:48

6

此錯誤可能會約由於對PDF 128位AES加密,見https://github.com/mstamy2/PyPDF2/issues/53

一個解決辦法是解密所有isEncrypted PDF文件以「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')