Algumas revistas geram um PDF diferente para cada download. O APS, por exemplo, armazena o tempo e o endereço IP no PDF.
Ou há uma versão em papel com hiperlinks e outra com referências de texto.
Como é possível encontrar downloads duplicados de papéis com conteúdo igual a 90% em um sistema Linux usando software de código aberto?
Eu estive pensando em converter os arquivos PDF em texto sem formatação em um diretório temporário com pdf2txt
. Então eu poderia filtrar todos os nomes de arquivos que diff a b
resultem em mais de x linhas. Mas isso não é nada elegante e falhará com as publicações digitalizadas. Os periódicos geralmente não fornecem texto de OCR para publicações antigas.
Também tentei compare
no pacote ImageMagick, mas não consegui lidar com arquivos PDF de várias páginas com esta ferramenta.
O diffpdf 2.1.1 faz um bom trabalho em uma GUI em dois arquivos, mas não consegui descobrir como aplicá-lo em muitos arquivos, e as versões recentes não estão disponíveis sob nenhuma licença de código aberto.
fonte
blah.pdf[1]
chamará a página desejada do documento.Respostas:
Como editores diferentes usam métodos diferentes para "marcar" os PDFs, é necessário comparar sem levar em consideração as marcações.
Você também precisa de um método eficiente para comparar um novo PDF com todos os PDFs já baixados, caso faça o download repetido do mesmo PDF e, por exemplo, esteja marcado com o IP e / ou carimbo de data / hora, conforme sugerido. Você não deseja usar um mecanismo de comparação demorado que compara cada novo PDF com muitos PDFs já baixados
O que você precisa é de um utilitário que retire cada uma das marcações possíveis e gere um hash dos dados restantes. Você precisará manter um mapa de nome de arquivo hash →, que pode estar em um arquivo simples, e se um hash computado já estiver no arquivo, você terá uma duplicata (e a excluirá ou fará o que for necessário) e se o hash ainda não estiver lá, você adiciona o hash e o nome do arquivo. O arquivo seria algo como:
Esse arquivo é negligentemente pequeno comparado aos PDFs originais. Se você possui milhões de PDFs, considere armazenar esses dados em um banco de dados. Por questões de eficiência, convém incluir o tamanho do arquivo e o número de páginas (
pdfinfo | egrep -E '^Pages:' | grep -Eo '[0-9]*'
).O procedimento acima elimina o problema de remover as marcações e gerar o hash. Se você souber de onde vem o PDF ao chamar a rotina de geração de hash (ou seja, se você fizer os downloads programaticamente), poderá ajustar a geração de hash com base nisso. Mas mesmo sem isso, existem várias possibilidades para geração de hash:
pdfinfo -E file.pdf | grep -E '^(Author:)|(Title:) | md5sum
para obter o hash. Você também pode incluir o número de páginas no cálculo do hash ('Pages:
' napdfinfo
saída).imagemagick
). Você pode usarpdfimages
para extrair as informações da imagem em um arquivo temporário.pdftext
para extrair o texto, filtrar a marcação (se você filtrar um pouco demais, isso não é um problema) e depois gerar o hash com base em aquele.Além disso, você pode comparar se o tamanho do arquivo antigo encontrado via hash e verificar se está dentro de determinadas margens com o novo arquivo. Compactação e ifferências em seqüências de caracteres (IP / data e hora) só devem resultar em menos de um por cento de diferença.
Se você conhece o método que o editor usa ao determinar o hash, é possível aplicar diretamente o método "correto" acima, mas mesmo sem isso, você pode verificar os metadados e aplicar algumas heurísticas ou determinar o número de imagens em um arquivo e compare isso com o número de páginas (se estiverem próximas, você provavelmente terá um documento que consiste em digitalizações).
pdftext
na imagem digitalizada, os PDFs também têm uma saída reconhecível.Como base para trabalhar, criei um pacote python que está no bitbucket e / ou pode ser instalado no PyPI usando
pip install ruamel.pdfdouble
. Isso fornece opdfdbl
comando que faz a digitalização conforme descrito acima em metadados, imagens extraídas ou texto. Ele não faz qualquer filtragem de marcas (ainda) , mas o readme descreve quais (dois) métodos para aumentar a não acrescentar que.O leia-me incluído:
ruamel.pdfdouble
este pacote fornece o
pdfdbl
comando:Isso percorrerá os diretórios fornecidos como argumento e, para os arquivos PDF encontrados, criará um hash com base em (em ordem):
Isso pressupõe que pdfinfo, pdfimages e pdftotext` do pacote poppler-utils estejam disponíveis.
Um "banco de dados" é construído
~/.config/pdfdbl/pdf.lst
contra o qual outras verificações são testadas.Removendo marcações
No
ruamel/pdfdouble/pdfdouble.py
existem dois métodos que podem ser melhoradas para filtrar marcas no PDF que torná-los menos exclusivo e fazer praticamente os mesmos arquivos para ter diferentes hashes.Para texto, o método
PdfData.filter_for_marking
deve ser estendido para remover e marcações da sequência que é seus argumentos e retornar o resultado.Para imagens digitalizadas, o método
PdfData.process_image_and_update
precisa ser aprimorado, por exemplo, cortando as linhas X inferior e superior da imagem e removendo qualquer texto cinza de fundo, definindo todos os pixels pretos para branco. Essa função precisa atualizar o hash passado usando o.update()
método que passa nos dados filtrados.Restrições
O "banco de dados" atual não pode manipular caminhos que contêm novas linhas
Atualmente, este utilitário é apenas Python 2.7.
As partes de string em conformidade com o IP podem ser substituídas pelo
re
módulo do Python :fonte
pdfrw
para extrair metadados também, mas isso não pode lidar com arquivos pdf criptografados, ondepdfinfo
pode.Eu daria
pdftotext
outra chance, pelo menos para os PDFs em sua coleção que realmente possuem texto (caso contrário, você precisaria executar o OCR), usando uma ferramenta melhor para processar a saída.Depois de obter sua saída de texto (suja), execute-a através de um programa projetado para determinar semelhanças (em vez
diff
das diferenças linha por linha, o que seria um caminho rápido para a loucura).Considere algo como o String: Similarity do perl ou o programa simhash (que está disponível no Debian, mas não no Fedora / RHEL).
fonte
Os PDFs contêm metadados e acabei de verificar vários artigos relacionados à física de diferentes editores e todos eles têm pelo menos o atributo "Título". Para alguns, o título é o título real da publicação, para alguns, contém o DOI ou identificadores semelhantes. De qualquer forma, todo artigo que verifiquei contém o título, e é sempre algo único para a publicação em questão.
Você pode usar
pdftk
para acessar os metadados dos PDFs e compará-los. Para seu propósito, isso definitivamente deve ser suficiente e é muito mais rápido do quepdftotext
se o desempenho fosse um problema. Caso um artigo realmente não deva ter metadados de título, você ainda poderá recorrer apdftotext
.Para despejar todos os metadados em um arquivo de texto (ou stdout) para processamento adicional, use
ou consulte o manual para mais opções.
Se você quiser experimentar o ImageMagick ,
compare
mas várias páginas causam um problema, você também pode usarpdftk
para extrair páginas únicas e comparar todas separadamente (talvez apenas comparar uma única seja suficiente).Aqui está um trecho de código que usa essa abordagem para criar uma
diff
saída semelhante a PDF para PDFs de várias páginas: https://gist.github.com/mpg/3894692fonte
Você já olhou para o PDF Content Comparer ? Existem opções de linha de comando que devem permitir que você automatize o processo.
Você pode executar algum tipo de lógica no log de diferenças criado para ver como elas são semelhantes.
Caso contrário, tente dividir os PDFs em vários arquivos temporariamente e compará-los dessa maneira. Você provavelmente ainda teria duplicatas dessa maneira, no entanto. Um PDF pode ter apenas uma página em branco extra ou algo que faria com que todas as páginas subseqüentes fossem comparadas como completamente diferentes.
fonte
Após uma humilde contribuição para a discussão (resposta parcial):
Depois de convertido em texto, usaria o seguinte para calcular a smilaridade do arquivo (com base na diferença de palavras):
(1) produz um resultado como
(2) = 93
fonte
Eu tenho um script que analisa um pdf e primeiro tenta extrair texto usando
pdftotext
, mas se isso falhar (como acontece com um documento digitalizado), ele usa o ghostscript para transformar um PDF digitalizado com várias páginas em uma série de arquivos png e, em seguida, usa o tesseract para converter esta série em um único arquivo de texto. Se a digitalização for de qualidade suficiente, ele faz um bom trabalho. Seria fácil adicionar código comparando o texto entre arquivos, mas eu não tive esse requisito.O ghostscript e o tesseract são de código aberto e funcionam a partir da linha de comando.
fonte
pdfimages
o pacote poppler sem perda adicional de qualidade que poderia obter com a renderização através do ghostscript (que influencia negativamente qualquer OCR que você deseja fazer).pdfimages
está fazendo o mesmo que ghostscript (gs
) aqui, isto é, extraindo imagens de pdf para jpg / png. Por que é melhor nisso do quegs
?gs
/ /tesseract
(formato intermediário png) funciona um pouco melhor quepdfimages
/tesseract
(formato intermediário pbm).pdfimages
é mais rápido.Eu ofereceria o perl como uma solução. Existe um módulo chamado
CAM::PDF
que permite extrair ... conteúdo em PDF.Funciona um pouco assim:
Você pode extrair o texto e comparar isso.
Para documentos digitalizados apenas - é muito mais difícil, mas supondo que eles estejam usando as mesmas imagens de base (por exemplo, não as digitalizou separadamente), provavelmente você poderá usar:
Não testei particularmente bem, porque não tenho seus documentos de origem. Eu acho que essa abordagem deve funcionar - você não está comparando o conteúdo real da imagem, porque ... bem, isso é realmente difícil. Mas você deve conseguir reconhecer imagens semelhantes dos metadados.
Para PDFs idênticos com metadados diferentes, algo simples como hash do conteúdo do texto e dos metadados da imagem deve ser suficiente.
fonte
Há um aplicativo Linux, chamado recoll . Ele pode executar a tarefa, mas apenas para PDFs com camada de texto.
fonte
recoll
parece ser um mecanismo de busca na área de trabalho. Eu não conseguia ver como usá-lo para encontrar duplicatas.recoll
usapdftotext
para lidar com PDFs, que é o que o OP está tentando evitar aqui.