2014-10-07 9 views
7

Attualmente sto usando PyPDF 2 come dipendenza.PyPDF 2 Decrypt Not

ho incontrato alcuni file crittografati e trattati loro come si farebbe normalmente (nel codice seguente):

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

mio percorsofile sembra qualcosa come "~/bla/FDJKL492019 21490, LFS.pdf" PDF.decrypt ("") restituisce 1, il che significa che ha avuto successo. Ma quando colpisce stampa PDF.getNumPages(), genera ancora l'errore, "PyPDF2.utils.PdfReadError: File non è stato decodificato".

Come si elimina questo errore? Posso aprire il file PDF semplicemente facendo doppio clic (che di default si apre con Adobe Reader).

risposta

5

Per rispondere alla mia domanda: Se nel nome del file sono presenti NESSUNO spazio, la funzione di decodifica di PyPDF 2 fallirà in ultima analisi nonostante la restituzione di un codice di successo. Cerca di attenersi ai caratteri di sottolineatura durante la denominazione dei tuoi PDF prima di eseguirli tramite PyPDF2.

Per esempio,

Piuttosto che "FDJKL492019 21490, LFS.pdf" fare qualcosa come "FDJKL492019_21490_, LFS.pdf".

+0

Ben individuato! Deve essere una limitazione di Python o di questa particolare libreria in particolare (non ha nulla a che fare con il formato PDF). Puoi dirlo sul sito da dove l'hai preso. – usr2564301

+0

Sembra che fallisca anche quando si usano caratteri speciali "®ø" ecc. – rsm

6

Questo errore può accadere a causa di crittografia a 128-bit AES sulla pdf, vedere https://github.com/mstamy2/PyPDF2/issues/53

Una soluzione è di decifrare tutti i PDF IsEncrypted con "QPDF"

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

Anche se il vostro PDF fa non appare protetto da password, potrebbe comunque essere crittografato senza password. Il frammento di cui sopra presuppone questo è il caso.

0

Non ha nulla a che fare se il file è stato decodificato o meno quando si utilizza il metodo getNumPages().

Se diamo uno sguardo al codice sorgente di 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) 

noteremo che è la proprietà self.isEncrypted controllare il flusso. E come tutti sappiamo, la proprietà isEncrypted è di sola lettura e non è modificabile anche quando il pdf è decodificato.

Quindi, il modo più semplice per gestire la situazione è solo aggiungere la password come argomento la parola-chiave con stringa vuota come valore di default e passare la password quando si utilizza il metodo getNumPages() e qualsiasi altro metodo di costruire al di là di esso

1

Il il seguente codice potrebbe risolvere questo problema:

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