2009-02-17 39 views
13

Obtengo un archivo a través de un HTTP-Upload y necesito estar seguro de que es un archivo pdf. El lenguaje de programación es Python, pero esto no debería importar.Compruebe si un archivo PDF es válido (Python)

pensé en las siguientes soluciones:

  1. Comprobar si los primeros bytes de la cadena son "% PDF". Esto no es una buena verificación pero evita que el uso cargue otros archivos accidentalmente.

  2. Pruebe la libmagic (el comando "file" en el bash lo usa). Esto hace exactamente lo mismo cheque como 1.

  3. Tome un lib y tratar de leer la página-conteo fuera del archivo. Si la lib es capaz de leer un conteo de páginas, debe ser un pdf válido. Problema: No sé un lib para Python que puede hacer esto

Así Alguien tiene alguna solución para un lib u otro truco?

Gracias

Respuesta

10

Las dos bibliotecas PDF más comúnmente usados ​​para Python son:

Ambos son pura pitón por lo que debe ser fácil de instalar y ser multiplataforma.

Con pyPdf probablemente sería tan simple como hacer:

from pyPdf import PdfFileReader 
doc = PdfFileReader(file("upload.pdf", "rb")) 

Esto debería ser suficiente, pero ahora tendrá docdocumentInfo() y numPages() métodos si desea hacer una comprobación posterior.

Como Carl respondió, pdftotext también es una buena solución, y probablemente sea más rápida en documentos muy grandes (especialmente aquellos con muchas referencias cruzadas). Sin embargo, podría ser un poco más lento en PDF pequeños debido a la sobrecarga del sistema de bifurcar un nuevo proceso, etc.

2

Si estás en una caja OS X o Linux, se puede usar Pdftotext (parte de Xpdf, que se encuentra here). Si transfiere un PDF que no sea PDF a pftftotext, seguramente lo ladrará, y puede usar commands.getstatusoutput para obtener la salida y analizar estas advertencias.

Si está buscando una solución independiente de la plataforma, es posible que pueda hacer uso de pyPdf.

Editar: No es elegante, pero parece que el PdfFileReader de pyPdf lanzará un IOError (22) si intenta cargar un archivo que no sea PDF.

10

En un proyecto si es mío, necesito verificar el tipo de mime de algún archivo cargado. Me basta con utilizar el comando de archivo de esta manera:

from subprocess import Popen, PIPE 
filetype = Popen("/usr/bin/file -b --mime -", shell=True, stdout=PIPE, stdin=PIPE).communicate(file.read(1024))[0].strip() 

Usted, por supuesto, puede ser que desee mover el comando real en algún archivo de configuración como también mandan algo varían entre las opciones de línea de sistemas operativos (por ejemplo, mac).

Si solo necesita saber si es un PDF o no y no necesita procesarlo de todos modos, creo que el comando de archivo es una solución más rápida que una lib. Hacerlo a mano también es posible, pero el comando de archivo le da más flexibilidad si desea verificar diferentes tipos.

+0

+1 por simplicidad. Si solo quieres estar bastante seguro de que lo que tienes es al menos intentar ser un PDF, esto es tanto simple como rápido. – technicalbloke

0

¿Por válido quiere decir que puede mostrarse en un visor de PDF o que el texto puede extraerse? Son dos cosas muy diferentes.

Si solo quiere comprobar que realmente se ha cargado un archivo PDF, entonces la solución pyPDF, o algo similar, funcionará.

Sin embargo, si desea comprobar que el texto se puede extraer, ¡encontrará todo un mundo de dolor! Usar pdftotext sería una solución simple que funcionaría en la mayoría de los casos pero de ninguna manera es 100% exitosa. Hemos encontrado muchos ejemplos de archivos PDF que pftftotext no puede extraer, pero las bibliotecas de Java como iText y PDFBox sí pueden.

8

ya que al parecer no PyPdf ni ReportLab es lo habrá mas, la solución actual que encontré (a partir de 2015) es utilizar PyPDF2 y atrapar excepciones (y posiblemente analizar getDocumentInfo())

import PyPDF2 

with open("testfile.txt", "w") as f: 
    f.write("hello world!") 

try: 
    PyPDF2.PdfFileReader(open("testfile.txt", "rb")) 
except PyPDF2.utils.PdfReadError: 
    print("invalid PDF file") 
else: 
    pass 
Cuestiones relacionadas