Soy un recién graduado en matemáticas puras que solo ha tomado algunos cursos básicos de programación. Estoy haciendo una pasantía y tengo un proyecto de análisis de datos interno. Tengo que analizar los PDF internos de los últimos años. Los archivos PDF están "asegurados". En otras palabras, están encriptados. No tenemos contraseñas en PDF, aún más, no estamos seguros de si existen contraseñas. Pero tenemos todos estos documentos y podemos leerlos manualmente. También podemos imprimirlos. El objetivo es leerlos con Python porque es el lenguaje que tenemos alguna idea.
Primero, intenté leer los archivos PDF con algunas bibliotecas de Python. Sin embargo, las bibliotecas de Python que encontré no leen archivos PDF encriptados. En ese momento, tampoco podía exportar la información con Adobe Reader.
En segundo lugar, decidí descifrar los archivos PDF. Tuve éxito usando la biblioteca Python pykepdf. ¡Pykepdf funciona muy bien! Sin embargo, los PDF descifrados no se pueden leer tan bien con las bibliotecas de Python del punto anterior ( PyPDF2 y Tabula ). En este momento, hemos realizado algunas mejoras porque con Adobe Reader puedo exportar la información de los PDF descifrados, pero el objetivo es hacer todo con Python.
El código que estoy mostrando funciona perfectamente con PDF sin cifrar, pero no con PDF cifrados. No funciona con los PDF descifrados que también se obtuvieron con pykepdf.
No escribí el código. Lo encontré en la documentación de las bibliotecas de Python Pykepdf y Tabula . La solución PyPDF2 fue escrita por Al Sweigart en su libro, " Automatice las cosas aburridas con Python ", que recomiendo encarecidamente. También verifiqué que el código funciona bien, con las limitaciones que expliqué antes.
Primera pregunta, ¿por qué no puedo leer los archivos descifrados, si los programas funcionan con archivos que nunca se han cifrado?
Segunda pregunta, ¿podemos leer con Python los archivos descifrados de alguna manera? ¿Qué biblioteca puede hacerlo o es imposible? ¿Todos los PDF descifrados son extraíbles?
¡¡¡Gracias por su tiempo y ayuda!!!
Encontré estos resultados usando Python 3.7, Windows 10, Jupiter Notebooks y Anaconda 2019.07.
Python
import pikepdf
with pikepdf.open("encrypted.pdf") as pdf:
num_pages = len(pdf.pages)
del pdf.pages[-1]
pdf.save("decrypted.pdf")
import tabula
tabula.read_pdf("decrypted.pdf", stream=True)
import PyPDF2
pdfFileObj=open("decrypted.pdf", "rb")
pdfReader=PyPDF2.PdfFileReader(pdfFileObj)
pdfReader.numPages
pageObj=pdfReader.getPage(0)
pageObj.extractText()
Con Tabula, recibo el mensaje "el archivo de salida está vacío".
Con PyPDF2, solo obtengo '/ n'
ACTUALIZACIÓN 10/3/2019 Pdfminer.six (Versión de noviembre de 2018)
Obtuve mejores resultados usando la solución publicada por DuckPuncher . Para el archivo descifrado, obtuve las etiquetas, pero no los datos. Lo mismo sucede con el archivo encriptado. Para el archivo que nunca ha sido encriptado funciona perfecto. Como necesito los datos y las etiquetas de los archivos cifrados o descifrados, este código no me funciona. Para ese análisis, utilicé pdfminer.six, que es la biblioteca Python que se lanzó en noviembre de 2018. Pdfminer.six incluye una biblioteca pycryptodome. Según su documentación, " PyCryptodome es un paquete autónomo de Python de primitivas criptográficas de bajo nivel ..."
El código está en la pregunta de intercambio de pila: ¿ Extraer texto de un archivo PDF usando PDFMiner en Python?
Me encantaría si quieres repetir mi experimento. Aquí está la descripción:
1) Ejecute los códigos mencionados en esta pregunta con cualquier PDF que nunca haya sido encriptado.
2) Haga lo mismo con un PDF "Seguro" (este es un término que utiliza Adobe), lo llamo PDF encriptado. Use un formulario genérico que puede encontrar usando Google. Después de descargarlo, debe completar los campos. De lo contrario, estaría buscando etiquetas, pero no campos. Los datos están en los campos.
3) Descifre el PDF encriptado usando Pykepdf. Este será el PDF descifrado.
4) Ejecute los códigos nuevamente usando el PDF descifrado.
ACTUALIZACIÓN 10/4/2019 Camelot (Versión Julio 2019)
Encontré la biblioteca de Python Camelot. Tenga cuidado de que necesita camelot-py 0.7.3.
Es muy potente y funciona con Python 3.7. Además, es muy fácil de usar. Primero, también necesita instalar Ghostscript . De lo contrario, no funcionará. También necesitas instalar Pandas . No utilice pip install camelot-py . En su lugar, use pip install camelot-py [cv]
El autor del programa es Vinayak Mehta. Frank Du comparte este código en un video de YouTube "Extraiga datos tabulares de PDF con Camelot usando Python".
Verifiqué el código y funciona con archivos sin cifrar. Sin embargo, no funciona con archivos cifrados y descifrados, y ese es mi objetivo .
Camelot está orientado a obtener tablas de archivos PDF.
Aquí está el código:
Python
import camelot
import pandas
name_table = camelot.read_pdf("uncrypted.pdf")
type(name_table)
#This is a Pandas dataframe
name_table[0]
first_table = name_table[0]
#Translate camelot table object to a pandas dataframe
first_table.df
first_table.to_excel("unencrypted.xlsx")
#This creates an excel file.
#Same can be done with csv, json, html, or sqlite.
#To get all the tables of the pdf you need to use this code.
for table in name_table:
print(table.df)
ACTUALIZACIÓN 10/7/2019 Encontré un truco. Si abro el pdf seguro con Adobe Reader, y lo imprimo usando Microsoft a PDF, y lo guardo como PDF, puedo extraer los datos usando esa copia. También puedo convertir el archivo PDF a JSON, Excel, SQLite, CSV, HTML y otros formatos. Esta es una posible solución a mi pregunta. Sin embargo, todavía estoy buscando una opción para hacerlo sin ese truco porque el objetivo es hacerlo al 100% con Python. También me preocupa que si se usa un mejor método de cifrado, el truco tal vez no funcione. A veces necesita usar Adobe Reader varias veces para obtener una copia extraíble.
ACTUALIZACIÓN 10/8/2019. Tercera pregunta Ahora tengo una tercera pregunta. ¿Todos los archivos PDF seguros / encriptados están protegidos con contraseña? ¿Por qué pikepdf no funciona? Supongo que la versión actual de pikepdf puede romper algún tipo de cifrado, pero no todos. @constt mencionó que PyPDF2 puede romper algún tipo de protección. Sin embargo, le respondí que encontré un artículo que PyPDF2 puede romper los cifrados hechos con Adobe Acrobat Pro 6.0, pero no con versiones posteriores.
fuente
PyPDF2
, todo funciona bien. Utilicépdftk
así como servicios en línea para encriptar archivos. ¿Puedes publicar enlaces a archivos pdf "problemáticos"?qpdf
para descifrar tus archivos? En el caso de que funcione, puede llamarlo desde su script usando elsubprocess
módulo para descifrar archivos antes de analizarlos.Respuestas:
ÚLTIMA ACTUALIZACIÓN 10-11-2019
No estoy seguro si entiendo tu pregunta por completo. El siguiente código se puede refinar, pero se lee en un PDF cifrado o no cifrado y extrae el texto. Avíseme si he entendido mal sus requisitos.
Noté que a su código pikepdf utilizado para abrir un PDF encriptado le faltaba una contraseña, lo que debería haber arrojado este mensaje de error:
Puede usar tika para extraer el texto del decrypted.pdf creado por pikepdf .
Decidí hacer un par de pruebas usando varios archivos PDF encriptados.
Llamé a todos los archivos cifrados 'encrypted.pdf' y todos usaron la misma contraseña de cifrado y descifrado.
Adobe Acrobat 9.0 y posterior: nivel de cifrado AES de 256 bits
Adobe Acrobat 6.0 y posterior - nivel de cifrado RC4 de 128 bits
Adobe Acrobat 3.0 y posterior: nivel de cifrado RC4 de 40 bits
Adobe Acrobat 5.0 y posterior - nivel de cifrado RC4 de 128 bits
Adobe Acrobat 9.0 y posterior: nivel de cifrado AES de 256 bits
PyPDF2 no puede descifrar archivos PDF de Acrobat => 6.0
Problemas de descifrado de PyPDF4
ACTUALIZACIÓN SECCIÓN 10-11-2019
Adobe PDFs nivel de seguridad
Los archivos PDF de Adobe tienen varios tipos de controles de seguridad que el propietario del documento puede habilitar. Los controles pueden aplicarse con una contraseña o un certificado.
Cifrado de documentos (forzado con una contraseña de documento abierto)
Edición e impresión restrictivas (aplicadas con una contraseña de permisos)
La imagen a continuación muestra un PDF de Adobe encriptado con encriptación AES de 256 bits. Para abrir o imprimir este PDF se requiere una contraseña. Cuando abra este documento en Adobe Reader con la contraseña, el título indicará SEGURO
Este documento requiere una contraseña para abrir con los módulos de Python que se mencionan en esta respuesta. Si intenta abrir un PDF encriptado con Adobe Reader. Deberías ver esto:
Si no recibe esta advertencia, el documento no tiene habilitados los controles de seguridad o solo tiene habilitados los de edición e impresión restrictivos.
La imagen a continuación muestra la edición restrictiva habilitada con una contraseña en un documento PDF. La impresión de notas está habilitada . Para abrir o imprimir este PDF no se requiere una contraseña . Cuando abra este documento en Adobe Reader sin una contraseña, el título indicará SEGURO Esta es la misma advertencia que el PDF encriptado que se abrió con una contraseña.
Cuando imprime este documento en un nuevo PDF, se elimina la advertencia SEGURO porque se ha eliminado la edición restrictiva.
Todos los productos de Adobe aplican las restricciones establecidas por la contraseña de permisos. Sin embargo, si los productos de terceros no son compatibles con esta configuración, los destinatarios del documento pueden omitir algunas o todas las restricciones establecidas.
Sobre romper el cifrado de PDF
Ni PyPDF2 ni PyPDF4 están diseñados para romper la función de contraseña de apertura de documento de un documento PDF. Ambos módulos arrojarán el siguiente error si intentan abrir un archivo PDF protegido con contraseña cifrada.
La función de contraseña de apertura de un archivo PDF encriptado se puede omitir utilizando una variedad de métodos, pero una sola técnica podría no funcionar y algunas no serán aceptables debido a varios factores, incluida la complejidad de la contraseña.
El cifrado de PDF funciona internamente con claves de cifrado de 40, 128 o 256 bits, según la versión de PDF. La clave de cifrado binario se deriva de una contraseña proporcionada por el usuario. La contraseña está sujeta a restricciones de longitud y codificación.
Por ejemplo, PDF 1.7 Adobe Extension Level 3 (Acrobat 9 - AES-256) introdujo caracteres Unicode (65.536 caracteres posibles) y aumentó la longitud máxima a 127 bytes en la representación UTF-8 de la contraseña.
fuente
Puede intentar manejar el error que producen estos archivos cuando abre estos archivos sin contraseña.
Puede usar el pdf_obj devuelto para su trabajo de análisis. Además, puede proporcionar la contraseña en caso de que tenga un PDF encriptado.
fuente
Para tabula-py, puede probar la opción de contraseña con read_pdf. Depende de la función de tabula-java, así que no estoy seguro de qué cifrado es compatible.
fuente