İçeriğe göre yinelenen PDF dosyalarını bulma


9

Bazı dergiler her indirme için farklı bir PDF oluşturur. Örneğin APS, zamanı ve IP adresini PDF'ye kaydeder.

Ya da hiper bağlantıları olan ve metin referansları olan bir kağıt versiyonu vardır.

Açık kaynaklı yazılım kullanarak bir linux sisteminde% 90 eşit içeriğe sahip kağıtların yinelenen indirmelerini bulmak nasıl mümkün olabilir?

PDF dosyalarını geçici bir dizindeki düz metne dönüştürmeyi düşünüyorum pdf2txt. Sonra diff a bx dosyalarından daha fazla sonuç veren tüm dosya adlarını filtreleyebilirim . Ancak bu hiç de zarif değil ve taranmış yayınlarda başarısız olacak. Dergiler genellikle eski yayınlar için OCR metni sağlamaz.

compareImageMagick takımında da denedim , ancak bu araçla çok sayfalı PDF dosyalarını işleyemedim.

diffpdf 2.1.1 , iki dosya üzerinde bir GUI'de iyi bir iş çıkarır , ancak birçok dosyaya nasıl uygulanacağını anlayamadım ve son sürümler herhangi bir açık kaynak lisansı altında mevcut değildir.


1
Cevaplar arasında çok farklı yaklaşımlar olduğundan, daha spesifik olmak ve soruyu açıklığa kavuşturmak iyi olabilir. Şimdi bilimsel makaleler de dahil olmak üzere farklı pdf dosyalarını karşılaştırmak için sağlam bir yol mu arıyorsunuz ya da sadece başlık veya DOI eşleşen tamamen kontrol olup olmadığını dergi makaleleri karşılaştırmak için verimli, zarif bir çözüm bulmaya çalışıyorsunuz.
inVader

Ben benzer bir çözüm arıyorum - şimdi her indirme pdf zaman ve ip kayıtları zaman sorunlu md5 kullanıyorum. Ben sayfalar arasında döngü bir sarmalayıcı komut dosyası ile imagemagick ile bir çözüm üzerinde çalışıyorum (ve muhtemelen günlük tarafından eklenen başlık durumunda ilk sayfayı atlamaya çalışın). Bunun mümkün olan en sağlam çözüm olduğuna eminim . Çok iyi çalışacağını biliyorsunuz çünkü bir kişinin iki belgeyi görsel olarak karşılaştırırken kullandığı yöntem aynı. Ayrıca belgenin oluşturulma biçiminden tamamen bağımsızdır, sadece görsel görünümüdür.
orion

Ayrıca, tek bir sayfa karşılaştırmasının muhtemelen yeterli olduğunu söyleyebilirim - bir sayfa aynı ise iki belgenin farklı olması pek olası değildir. Gösterim blah.pdf[1], belgeden istenen bir sayfayı çağıracaktır.
orion

Gerçekten bir veya her iki taramaya dayalı pdfs karşılaştırmak gerekirse Ben OCR kullanmaktan kaçınamıyorum düşünüyorum. Bu nedenle burada önerilen yaklaşımların birçoğu sorunu gerçekten çözmüyor.
gogoud

Yanıtlar:


4

Farklı yayıncılar PDF'leri "işaretlemek" için farklı yöntemler kullandığından, işaretleri dikkate almadan karşılaştırdığınızdan emin olmanız gerekir.

Aynı PDF'yi tekrar tekrar indirmeniz ve önerdiğiniz gibi IP ve / veya tarih-zaman damgası ile işaretlenmesi durumunda, yeni bir PDF'yi önceden indirilmiş tüm PDF'lerle karşılaştırmak için etkili bir yönteme de ihtiyacınız vardır. Her yeni PDF'yi önceden indirilmiş birçok PDF ile karşılaştıran zaman alıcı bir karşılaştırma mekanizması kullanmak istemezsiniz

İhtiyacınız olan şey, olası işaretlerin her birini ayıran ve kalan verilerin bir karmasını üreten bir yardımcı programdır. Basit bir dosyada olabilen bir karma → dosya adı eşlemesini tutmanız gerekir ve hesaplanmış bir karma zaten dosyadaysa, yinelenir (ve silebilir veya ne gerekiyorsa yapın) ve karma henüz değilse orada, karma ve dosya adını eklersiniz. Dosya şuna benzer:

6fcb6969835d2db7742e81267437c432  /home/anthon/Downloads/explanation.pdf
fa24fed8ca824976673a51803934d6b9  /home/anthon/orders/your_order_20150320.pdf

Bu dosya orijinal PDF'lere kıyasla önemsiz derecede küçük. Milyonlarca PDF'niz varsa, bu verileri bir veritabanında depolamayı düşünebilirsiniz. Verimlilik için dosya boyutunu ve sayfa sayısını buraya eklemek isteyebilirsiniz ( pdfinfo | egrep -E '^Pages:' | grep -Eo '[0-9]*').


Yukarıdakiler, sorunu işaretlerin çıkarılması ve karma üretilmesine itmektedir. Karma oluşturma rutini çağrılırken PDF'nin nereden geldiğini biliyorsanız (yani, indirmeleri programlı olarak yaparsanız) buna göre karma oluşturma işleminde ince ayar yapabilirsiniz. Ancak bu olmadan bile, karma üretimi için birkaç olasılık vardır:

  1. başlık ve yazar için meta veriler boş değilse ve "Acrobat" veya "PDF" gibi spesifik olmayan dizeler içermiyorsa, karmayı yalnızca yazar ve başlık bilgilerine göre oluşturabilirsiniz. pdfinfo -E file.pdf | grep -E '^(Author:)|(Title:) | md5sumKarma elde etmek için kullanın . Karma sayısını hesaplamak için sayfa sayısını da ekleyebilirsiniz ( çıktıda ' Pages:' pdfinfo).
  2. önceki kural işe yaramazsa ve PDF resim içeriyorsa, resimleri çıkarın ve birleştirilmiş resim verilerinde bir karma oluşturun. Görüntüler altbilgi veya üstbilgide "Joe Kullanıcısına Lisanslı" gibi bir metin içeriyorsa, karmayı hesaplamadan önce üst veya alt kısımdan X sayıda satır çekin. Bu işaretler büyük harfli gri arka plan metnindeyse, tamamen siyah olmayan pikselleri filtrelemediğiniz sürece (bunun için kullanabilirsiniz imagemagick) elbette işe yaramaz . pdfimagesGörüntü bilgilerini geçici bir dosyaya ayıklamak için kullanabilirsiniz .
  3. önceki kurallar işe yaramazsa (görüntü olmadığı için) pdftextmetni ayıklamak, işaretlemeyi filtrelemek (biraz filtrelerseniz, bu bir sorun değildir) ve ardından hash söyledi.

Ek olarak, karma yoluyla bulunan eski dosyanın dosya boyutunun karşılaştırılıp yeni dosyayla belirli kenar boşluklarında olup olmadığını görebilirsiniz. Dizelerdeki sıkıştırma ve farklılıklar (IP / tarih-saat damgası) yalnızca yüzde birden az farkla sonuçlanmalıdır.

Yayıncının karmayı belirlerken kullandığı yöntemi biliyorsanız, doğrudan yukarıdakilerin "doğru" yöntemini uygulayabilirsiniz, ancak bu olmadan bile meta verileri kontrol edebilir ve bazı sezgisel yöntemler uygulayabilir veya bir dosyadaki görüntü sayısını belirleyebilirsiniz ve sayfa sayısıyla karşılaştırın (yakınlarsa muhtemelen taramalardan oluşan bir belgeniz vardır). pdftexttaranan görüntüde PDF'lerin de tanınabilir bir çıktısı vardır.


Çalışmak için temel olarak bitbucket üzerinde olan ve / veya PyPI kullanılarak kurulabilen bir python paketi oluşturdum pip install ruamel.pdfdouble. Bu, pdfdblmeta veri, çıkarılan görüntüler veya metin üzerinde yukarıda açıklandığı gibi taramayı yapan komutu sağlar . İşaretlerin herhangi bir filtrelemesini yapmaz (henüz) , ancak benioku bunu eklemek için hangi (iki) yöntemi geliştireceğini açıklar.

Dahil benioku:

ruamel.pdfdouble

bu paket şu pdfdblkomutu sağlar:

pdfdbl scan dir1 dir2

Bu, bağımsız değişken olarak sağlanan dizinleri yürütebilir ve bulunan PDF dosyaları için aşağıdakileri temel alan bir karma oluşturun:

  • benzersiz ise meta veriler
  • görüntü sayısı
  • Metin

Bu, poppler-utils paketinden pdfinfo, pdfimages ve pdftotext’in kullanılabilir olduğunu varsayar.

Daha ~/.config/pdfdbl/pdf.lstfazla taramanın test edildiği bir "veritabanı" oluşturulur .

İşaretleri kaldırma

Gelen ruamel/pdfdouble/pdfdouble.pyonları daha az benzersiz yapmak ve farklı karmaları var hemen hemen aynı dosyaları yapmak PDF işaretleri filtrelemek için geliştirilmiş olabilir iki yöntem vardır.

Metin için yöntem PdfData.filter_for_marking, argümanları olan dizeden kaldırılacak ve işaretler çıkarılacak ve sonuç döndürülecek şekilde genişletilmelidir.

Taranan görüntüler için PdfData.process_image_and_update, örneğin görüntülerin alt ve üst X çizgilerini keserek ve tüm siyah pikselleri beyaza ayarlayarak gri arka plan metnini kaldırarak yöntemin iyileştirilmesi gerekir. Bu işlevin .update(), filtrelenmiş verilerden geçirilen yöntemi kullanarak geçirilen karmayı güncellemesi gerekir .

Kısıtlamalar

Geçerli "veritabanı", yeni satırlar içeren yolları işleyemiyor

Bu yardımcı program şu anda yalnızca Python 2.7'dir.


IP uyumlu dize parçaları Python remodülü ile değiştirilebilir:

import re
IPre = re.compile("(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}"
              "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])")

x = IPre.sub(' ', 'abcd 132.234.0.2 ghi')
assert x == 'abcd   ghi'

Geçmişte pdfrwmeta verileri ayıklamak için python paketini kullandım , ancak şifrelenmiş pdf dosyalarını işleyemiyor, nerede pdfinfoolabilir.
Anthon

2

Ben verirdim pdftotextaslında metin var Koleksiyonunuzdaki PDF'leri için en az çıkışını işlemek için daha iyi bir araç kullanarak, (aksi takdirde OCR çalıştırmak gerekiyordu), bir şans daha.

(Kirli) metin çıktısını aldıktan sonra, benzerlikleri belirlemek için tasarlanmış bir program aracılığıyla çalıştırın ( diffsatırlık farklılıklar yerine, deliliğe giden hızlı bir yol olacaktır).

Perl's String :: Similarity veya simhash programı (Debian'da mevcut ancak Fedora / RHEL'de mevcut değil) gibi bir şey düşünün .


2

PDF'ler meta veriler içeriyor ve ben sadece farklı yayıncılardan fizikle ilgili birkaç makaleyi kontrol ettim ve hepsinin en azından "Başlık" özelliği var. Bazıları için başlık, yayının gerçek başlığıdır, bazıları için DOI veya benzer tanımlayıcılar içerir. Her neyse, kontrol ettiğim her makale başlığı içeriyor ve her zaman verilen yayına özgü bir şey.

Sen kullanabilirsiniz pdftkPDF'leri meta verilerini erişebilir ve bu karşılaştırma. Amacınız için, bu kesinlikle yeterli olmalı ve pdftotextperformansın bir sorun olduğundan çok daha hızlı olmalıdır . Bir makalenin gerçekten başlık meta verilerine sahip olmaması durumunda, yine de geri dönebilirsiniz pdftotext.

Tüm meta verileri daha ileri işlem kullanımı için bir metin dosyasına (veya stdout'a) dökmek için

pdftk <PDF> dump_data output <TEXTFILE>

veya diğer seçenekler için kılavuza bakınız.

Denemek isterseniz ImageMagick 'in comparebir sorun nedeni ancak birden fazla sayfa, ayrıca kullanabilirsiniz pdftk(gerçi, belki sadece bir tek tane yeter karşılaştırarak) tek sayfaları çıkararak ayrı hepsini karşılaştırmak.

Çok diffsayfalı PDF'ler için benzer bir PDF çıktısı oluşturmak üzere bu yaklaşımı kullanan bir kod snippet'i : https://gist.github.com/mpg/3894692


1

PDF İçerik Karşılaştırıcısına baktınız mı ? Orada komut satırı seçenekleri işlemi otomatik hale izin vermelisiniz.

Ne kadar benzer olduklarını görmek için oluşturduğu fark günlüğünde bir tür mantık çalıştırabilirsiniz.

Başarısız olursa , PDF'leri geçici olarak birden fazla dosyaya bölmeyi ve bu şekilde karşılaştırmayı deneyebilirsiniz . Yine de muhtemelen bu şekilde kopyalarınız olur. Bir PDF'de fazladan boş bir sayfa veya sonraki tüm sayfaların tamamen farklı olarak karşılaştırılmasına neden olacak bir şey olabilir.


Bu kapalı kaynak programının en pahalı iki sürümü olabilir. Ücretsiz olması gerekmese de açık kaynaklı bir çözümü tercih ederim.
Jonas Stein

1

Tartışmaya mütevazi bir katkının ardından (kısmi cevap):

Metne dönüştürüldükten sonra (kelime farkına dayalı) dosya parlaklığını hesaplamak için aşağıdakileri kullanırdım:

wdiff -s -123 file1.txt file2.txt |    ## word difference statistics (1)
     grep -Po '(\d+)(?=% common)' |    ## 
     awk '{a+=$1}END{print a/2}'       ## (2)

(1) gibi bir sonuç üretir

file1.txt: 36 words  33 92% common  3 8% deleted  0 0% changed
file2.txt: 35 words  33 94% common  2 6% inserted  0 0% changed

(2) = 93


1

Bir pdf bakar ve ilk kullanarak metin ayıklamaya çalışır bir komut dosyası var pdftotext, ancak bu başarısız olursa (taranan bir belge ile olduğu gibi), çok sayfalı taranmış pdf png dosyaları bir dizi açmak için ghostscript kullanır ve sonra bu diziyi tek bir metin dosyasına dönüştürmek için tesseract kullanır . Tarama yeterli kalitede ise oldukça iyi bir iş çıkarır. Dosyalar arasındaki metni karşılaştırarak kod eklemek basit olurdu ama bu gereksinimim olmadı.

ghostscript ve tesseract açık kaynak kodludur ve komut satırından çalışır.


Taranan görüntüleri pdfimages, ghostscript ile oluştururken ek kalite kaybı olmadan poppler paketinden kullanarak doğrudan ayıklayabilirsiniz (bu, yapmak istediğiniz herhangi bir OCR'yi olumsuz etkiler).
Anthon

@Anthon bunu işaret ettiğiniz için teşekkürler, ama elbette pdfimagessadece ghostscript ( gs) ile aynı işi yapıyor yani pdf'den jpg / png'ye resim çıkarmak. Neden bu konuda daha iyi gs?
gogoud

Tüm taramalar aynı çözünürlüğe sahip olmadığı sürece (örneğin boşluk boşlukları atılmışsa değil) ve yalnızca görüntülerin kullandığı çözünürlükle aynı çözünürlükte oluşturursanız, ghostscript'in oluşturduğu oluşturma, görüntülerin piksellerini bozar
Anthon

@Anthon İlginç, biraz test yaptım. Sonuçlar çok benzer ancak gs/ tesseract(png ara formatı) pdfimages/ tesseract(pbm ara formatı) ' dan biraz daha iyi çalışıyor gibi görünüyor . pdfimagesolsa daha hızlı.
gogoud

0

Bir çözüm olarak perl öneririm. CAM::PDFPDF içeriği çıkarmanıza izin veren bir modül var .

Biraz şöyle çalışır:

#!/usr/bin/perl

use strict;
use warnings;

use CAM::PDF;

my $file = 'sample.pdf';

my $pdf = CAM::PDF->new($file);

my $word_count = 0;
for my $pagenum ( 1 .. $pdf->numPages ) {
    my $page_text = $pdf->getPageText($pagenum) );
    print $page_text; 
}

Metni çıkarabilir ve karşılaştırabilirsiniz.

Yalnızca taranan belgeler için - çok daha zordur, ancak aynı temel görüntüleri kullandıklarını varsayarsak (örneğin, bunları ayrı olarak taramadıysanız) muhtemelen şunları kullanabilirsiniz:

#!/usr/bin/perl

use strict;
use warnings;

use CAM::PDF;
use CAM::PDF::Renderer::Images;
use Data::Dumper; 

my $file = 'sample.pdf';

my $pdf = CAM::PDF->new($file);

my $word_count = 0;
for my $pagenum ( 1 .. $pdf->numPages ) {
    my $content =  $pdf->getPageText($pagenum);
    my $page = $pdf->getPageContentTree($pagenum);
    my $gs = $page->findImages();
    my @imageNodes = @{$gs->{images}};
    print Dumper \@imageNodes;

    print Dumper \$gs;
}

Özellikle iyi test etmedim, çünkü kaynak belgelerin yok. Ben düşünüyorum bu yaklaşım olsa hile yapmak gerekir - Eğer, çünkü gerçek görüntü içeriği karşılaştırarak değiliz .... iyi, gerçekten zor olduğunu. Ancak, meta verilerdeki benzer görselleri tanıyabilmeniz gerekir.

İçin aynı farklı meta verilerle PDF, metin içeriği karma gibi sonra bir şey basit ve görüntü meta hile yapmak gerekir.


-1

Recoll adı verilen bir Linux uygulaması var . Görevi gerçekleştirebilir, ancak yalnızca metin katmanı olan pdf'ler için.


2
Bana recollgöre bir masaüstü arama motoru gibi görünüyor. Yinelenenleri bulmak için nasıl kullanılacağını göremedim.
Jonas Stein

1
recollpdftotextPDF'leri işlemek için kullanır , bu da OP'nin burada kaçınmaya çalıştığı şeydir.
John WH Smith
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.