Algunas revistas generan un PDF diferente para cada descarga. APS, por ejemplo, almacena el tiempo y la dirección IP en el PDF.
O hay una versión en papel con hipervínculos y otra con referencias de texto.
¿Cómo es posible encontrar descargas duplicadas de documentos con un contenido igual al 90% en un sistema Linux utilizando software de código abierto?
He estado pensando en convertir los archivos PDF a texto sin formato en un directorio temporal con pdf2txt
. Entonces podría filtrar todos los nombres de archivo que diff a b
resultan más de x líneas. Pero esto no es elegante en absoluto y fallará con las publicaciones escaneadas. Las revistas a menudo no proporcionan texto de OCR para publicaciones antiguas.
También probé compare
en el paquete ImageMagick, pero no pude manejar archivos PDF multipágina con esta herramienta.
diffpdf 2.1.1 hace un buen trabajo en una GUI en dos archivos, pero no pude descubrir cómo aplicarlo en muchos archivos, y las versiones recientes no están disponibles bajo ninguna licencia de código abierto.
fuente
blah.pdf[1]
llamará a la página deseada del documento.Respuestas:
Dado que diferentes editores usan diferentes métodos para "marcar" los archivos PDF, debe asegurarse de comparar sin tener en cuenta las marcas.
También necesita un método eficiente para comparar un nuevo PDF con todos los PDF ya descargados en caso de que descargue repetidamente el mismo PDF y, por ejemplo, esté marcado con la IP y / o la marca de fecha y hora que sugiere. No desea utilizar un mecanismo de comparación que consume mucho tiempo que compara cada nuevo PDF con muchos PDF ya descargados
Lo que necesita es una utilidad que elimine cada una de las posibles marcas y genere un hash de los datos restantes. Deberá mantener un mapa de nombre de archivo hash →, que puede estar en un archivo simple, y si un hash calculado ya está en el archivo, tiene un duplicado (y eliminarlo o hacer lo que sea necesario) y si el hash aún no está allí, agrega el hash y el nombre del archivo. El archivo se vería así:
Ese archivo es negligentemente pequeño en comparación con los PDF originales. Si tiene millones de archivos PDF, puede considerar almacenar estos datos en una base de datos. Por razones de eficiencia, es posible que desee incluir el tamaño del archivo y el número de páginas allí (
pdfinfo | egrep -E '^Pages:' | grep -Eo '[0-9]*'
).Lo anterior empuja el problema a eliminar las marcas y generar el hash. Si sabe de dónde proviene el PDF al invocar la rutina de generación de hash (es decir, si realiza las descargas mediante programación), puede ajustar la generación de hash en función de eso. Pero incluso sin eso, hay varias posibilidades para la generación de hash:
pdfinfo -E file.pdf | grep -E '^(Author:)|(Title:) | md5sum
para obtener el hash. También puede incluir el número de páginas al calcular el hash ('Pages:
' en lapdfinfo
salida).imagemagick
). Puede usarpdfimages
para extraer la información de la imagen en un archivo temporal.pdftext
para extraer el texto, filtrar la marca (si filtra un poco demasiado, eso no es un problema) y luego generar el hash basado en ese.Además, puede comparar si el tamaño del archivo antiguo encontrado a través del hash y ver si está dentro de ciertos márgenes con el nuevo archivo. La compresión y las ifferencias en cadenas (IP / fecha-hora-sello) solo deberían dar como resultado una diferencia de menos del uno por ciento.
Si conoce el método que utiliza el editor para determinar el hash, puede aplicar directamente el método "correcto" de lo anterior, pero incluso sin eso puede verificar los metadatos y aplicar algunas heurísticas, o determinar la cantidad de imágenes en un archivo y compare eso con el número de páginas (si están cerca, probablemente tenga un documento que consta de escaneos).
pdftext
en PDF escaneados de imágenes también tiene una salida reconocible.Como base para trabajar, creé un paquete de Python que está en bitbucket y / o puede instalarse desde PyPI usando
pip install ruamel.pdfdouble
. Esto le proporciona elpdfdbl
comando que realiza el escaneo como se describió anteriormente en metadatos, imágenes extraídas o en texto. Todavía no filtra las marcas (todavía) , pero el archivo Léame describe qué (dos) métodos mejorar para agregar eso.El archivo Léame incluido:
ruamel.pdfdouble
Este paquete proporciona el
pdfdbl
comando:Esto recorrerá los directorios proporcionados como argumento y para los archivos PDF encontrados, cree un hash basado en (en orden):
Esto supone que pdfinfo, pdfimages y pdftotext` del paquete poppler-utils están disponibles.
Se crea una "base de datos" en la
~/.config/pdfdbl/pdf.lst
que se prueban más exploraciones.Eliminar marcas
En
ruamel/pdfdouble/pdfdouble.py
hay dos métodos que pueden ser mejoradas para filtrar las marcas en el PDF que los hacen menos único y hacer prácticamente los mismos archivos que tienen diferentes valores hash.Para el texto, el método
PdfData.filter_for_marking
debe extenderse para eliminar y marcar de la cadena que son sus argumentos y devolver el resultado.Para las imágenes escaneadas, el método
PdfData.process_image_and_update
debe mejorarse, por ejemplo, cortando las líneas X inferiores y superiores de las imágenes, y eliminando cualquier texto de fondo gris configurando todos los píxeles negros a blancos. Esta función necesita actualizar el hash pasado usando el.update()
método que pasa los datos filtrados.Restricciones
La "base de datos" actual no puede manejar rutas que contienen nuevas líneas
Esta utilidad es actualmente solo Python 2.7.
Las partes de cadena conformes a IP se pueden sustituir con el
re
módulo de Python :fuente
pdfrw
para extraer metadatos, pero eso no puede manejar archivos PDF cifrados, dondepdfinfo
sí.Daría
pdftotext
otra oportunidad, al menos para los archivos PDF en su colección que realmente tienen texto (de lo contrario, necesitaría ejecutar OCR), utilizando una herramienta mejor para procesar la salida.Una vez que tenga su salida de texto (sucio), ejecútelo a través de un programa diseñado para determinar similitudes (en lugar de
diff
las diferencias línea por línea, que sería un camino rápido hacia la locura).Considere algo como String :: Similarity de perl o el programa simhash (que está disponible en Debian pero no en Fedora / RHEL).
fuente
Los archivos PDF contienen metadatos y acabo de comprobar una serie de documentos relacionados con la física de diferentes editores y todos tienen al menos el atributo "Título". Para algunos, el título es el título real de la publicación, para algunos contiene el DOI o identificadores similares. De todos modos, cada artículo que revisé contiene el título, y siempre es algo exclusivo de la publicación dada.
Puede utilizar
pdftk
para acceder a los metadatos de los archivos PDF y compararlos. Para su propósito, esto definitivamente debería ser suficiente y es mucho más rápido quepdftotext
si el rendimiento es un problema. En caso de que un documento realmente no tenga metadatos de título, aún podría recurrir a élpdftotext
.Para volcar todos los metadatos en un archivo de texto (o stdout) para su posterior procesamiento, use
o consulte el manual para más opciones.
Si desea probar ImageMagick 's
compare
pero varias páginas causan un problema, también puede usarpdftk
para extraer páginas individuales y compararlas todas por separado (aunque tal vez solo una sola sea suficiente).Aquí hay un fragmento de código que utiliza este enfoque para crear una
diff
salida PDF similar a PDF de varias páginas: https://gist.github.com/mpg/3894692fuente
¿Has mirado en PDF Content Comparer ? Hay opciones de línea de comandos que deberían permitirle automatizar el proceso.
Podría ejecutar algún tipo de lógica en el registro de diferencias que crea para ver qué tan similares son.
Si no puede, intente dividir los PDF en varios archivos temporalmente y compararlos de esa manera. Sin embargo, probablemente todavía tengas duplicados de esa manera. Un PDF puede tener una página en blanco adicional o algo que haga que todas las páginas posteriores se comparen como completamente diferentes.
fuente
Después de una humilde contribución a la discusión (respuesta parcial):
Después de convertirlo a texto, usaría lo siguiente para calcular la similitud del archivo (basado en la diferencia de palabras):
(1) produce un resultado como
(2) = 93
fuente
Tengo un script que mira un pdf y primero intenta extraer el texto usando
pdftotext
, pero si esto falla (como lo hará con un documento escaneado), usa ghostscript para convertir un pdf escaneado de varias páginas en una serie de archivos png y luego usa tesseract para convertir esta serie en un solo archivo de texto. Si el escaneo es de calidad suficiente, hace un trabajo bastante bueno. Sería sencillo agregar código que compare el texto entre archivos, pero no he tenido este requisito.ghostscript y tesseract son de código abierto y funcionan desde la línea de comandos.
fuente
pdfimages
el paquete poppler sin pérdida adicional de calidad que podría obtener al renderizar a través de ghostscript (que influye negativamente en cualquier OCR que desee hacer).pdfimages
solo está haciendo lo mismo que ghostscript (gs
) aquí, es decir, extraer imágenes de pdf a jpg / png. ¿Por qué es mejor en esto quegs
?gs
/tesseract
(formato intermedio png) funciona un poco mejor quepdfimages
/tesseract
(formato intermedio pbm).pdfimages
Sin embargo, es más rápido.Ofrecería perl como solución. Hay un módulo llamado
CAM::PDF
que le permite extraer ... contenido PDF.Funciona un poco así:
Puedes extraer el texto y compararlo.
Para documentos escaneados solamente: es mucho más difícil, pero suponiendo que estén usando las mismas imágenes base (por ejemplo, no las han escaneado por separado), probablemente pueda usar:
No lo he probado particularmente bien, porque no tengo sus documentos fuente. Sin embargo, creo que este enfoque debería ser útil: no estás comparando el contenido real de la imagen, porque ... bueno, eso es realmente difícil. Pero debería poder reconocer imágenes similares de los metadatos.
Para archivos PDF idénticos con metadatos diferentes, entonces algo simple como el hash del contenido del texto y los metadatos de la imagen debería ser suficiente.
fuente
Hay una aplicación de Linux, llamada recoll . Puede realizar la tarea, pero solo para archivos PDF con capa de texto.
fuente
recoll
parece ser un motor de búsqueda de escritorio. No pude ver cómo usarlo para encontrar duplicados.recoll
utilizapdftotext
para manejar archivos PDF, que es lo que el OP está tratando de evitar aquí.