내용별로 중복 PDF 파일 찾기


9

일부 저널은 각 다운로드마다 다른 PDF를 생성합니다. 예를 들어 APS 는 시간과 IP 주소를 PDF에 저장합니다.

또는 하이퍼 링크가있는 용지 버전과 텍스트 참조가있는 용지 버전이 있습니다.

오픈 소스 소프트웨어를 사용하여 Linux 시스템에서 90 % 동일한 내용의 논문을 어떻게 중복 다운로드 할 수 있습니까?

와 함께 임시 디렉토리에서 PDF 파일을 일반 텍스트로 변환하려고 생각했습니다 pdf2txt. 그런 다음 diff a bx 줄보다 많은 모든 파일 이름을 필터링 할 수 있습니다. 그러나 이것은 전혀 우아하지 않으며 스캔 한 출판물로는 실패합니다. 저널은 종종 오래된 출판물에 대한 OCR 텍스트를 제공하지 않습니다.

compareImageMagick 제품군 에서도 시도했지만 이 도구로 여러 페이지 PDF 파일을 처리 할 수 ​​없습니다.

diffpdf 2.1.1 은 GUI에서 두 파일에 대해 잘 작동하지만 많은 파일에 적용하는 방법을 알 수 없었으며 최신 버전은 오픈 소스 라이센스로 제공되지 않습니다.


1
답변마다 매우 다른 접근 방식이 있기 때문에 질문을 더 구체적으로 설명하는 것이 좋습니다. 과학 논문을 포함하여 다른 pdf 파일을 비교할 수있는 강력한 방법을 찾고 있습니까? 아니면 제목이나 DOI가 일치하는지 확인하는 저널 기사를 비교할 수있는 효율적이고 우아한 솔루션을 찾고 있습니까?
inVader

비슷한 솔루션을 찾고 있습니다. 이제 모든 다운로드가 PDF에 시간과 IP를 기록 할 때 문제가되는 md5를 사용하고 있습니다. 래퍼 스크립트가있는 imagemagick 솔루션을 사용하여 페이지를 반복합니다 (저자가 첫 번째 페이지를 추가하여 저널이 추가 한 경우). 이것이 가장 강력한 솔루션 이라고 확신 합니다. 두 문서를 시각적으로 비교할 때 사람이 사용하는 것과 같은 방법이기 때문에 잘 작동한다는 것을 알고 있습니다. 또한 문서가 생성되는 방식과 시각적으로 만 완전히 독립적입니다.
오리온

또한 단일 페이지 비교만으로도 충분하다고 말하고 싶습니다. 한 페이지가 동일한 경우 두 문서가 다를 가능성이 낮습니다. 표기법 blah.pdf[1]은 문서에서 원하는 페이지를 호출합니다.
오리온

하나 또는 둘 다 스캔을 기반으로하는 PDF를 실제로 비교 해야하는 경우 OCR 사용을 피할 수 없다고 생각합니다. 따라서 여기에 제안 된 많은 접근법은 실제로 문제를 해결하지 못합니다.
gogoud

답변:


4

출판사마다 다른 PDF 표시 방법을 사용하므로 표시를 고려하지 않고 비교해야합니다.

동일한 PDF를 반복적으로 다운로드하고 제안한대로 IP 및 / 또는 날짜-시간 스탬프가 표시된 경우 새 PDF를 이미 다운로드 한 모든 PDF와 비교할 수있는 효율적인 방법이 필요합니다. 각각의 새 PDF를 이미 다운로드 한 많은 PDF와 비교하는 시간 소모적 인 비교 메커니즘을 사용하고 싶지 않습니다.

필요한 것은 각각의 가능한 표시를 제거하고 나머지 데이터의 해시를 생성하는 유틸리티입니다. 간단한 파일에있을 수있는 해시 → 파일 이름 맵을 유지해야하며 계산 된 해시가 이미 파일에 있으면 복제본이 있고 (삭제하거나 필요에 따라 수행) 해시가 아직없는 경우 거기에 해시와 파일 이름을 추가합니다. 파일은 다음과 같습니다.

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

이 파일은 원본 PDF에 비해 무시할 정도로 작습니다. 수백만 개의 PDF가있는 경우이 데이터를 데이터베이스에 저장하는 것이 좋습니다. 효율성을 위해 파일 크기와 페이지 수를 포함시킬 수 있습니다 ( pdfinfo | egrep -E '^Pages:' | grep -Eo '[0-9]*').


위의 내용은 표시를 제거하고 해시를 생성하는 문제를 해결합니다. 해시 생성 루틴을 호출 할 때 (예 : 프로그래밍 방식으로 다운로드를 수행하는 경우) PDF가 어디에서 오는지 알면이를 기반으로 해시 생성을 미세 조정할 수 있습니다. 그러나 그것 없이도 해시 생성에는 몇 가지 가능성이 있습니다.

  1. 제목 및 작성자의 메타 데이터가 비어 있지 않고 "Acrobat"또는 "PDF"와 같은 비 특정 문자열을 포함하지 않는 경우 저자 및 제목 정보만으로 해시를 생성 할 수 있습니다. pdfinfo -E file.pdf | grep -E '^(Author:)|(Title:) | md5sum해시를 얻는 데 사용 합니다. 해시 계산에 페이지 수를 포함시킬 수도 있습니다 ( 출력에 ' Pages:' pdfinfo).
  2. 이전 규칙이 작동하지 않고 PDF에 이미지가 포함 된 경우 이미지를 추출하고 결합 된 이미지 데이터에 해시를 생성하십시오. 이미지에 바닥 글이나 머리글에 "Joe 사용자에게 라이센스 부여"와 같은 텍스트가 포함 된 경우 해시를 계산하기 전에 맨 위 또는 맨 아래에있는 X 개의 줄을 제거하십시오. 그 표시가 큰 글자로 된 회색 배경 텍스트에 있으면 완전히 검은 색이 아닌 픽셀을 걸러 내지 않는 한 작동하지 않습니다 imagemagick. pdfimages이미지 정보를 임시 파일로 추출하는 데 사용할 수 있습니다 .
  3. 이전 규칙이 작동하지 않는 경우 (이미지가 없기 때문에) pdftext텍스트를 추출하고 표시를 걸러 내고 (작은 정도 필터링하면 문제가되지 않음) 해시를 기반으로 해시를 생성 할 수 있습니다 그.

또한 이전 파일의 파일 크기가 해시를 통해 발견되었는지 비교하고 새 파일의 특정 여백 내에 있는지 확인할 수 있습니다. 문자열의 압축 및 차이 (IP / 날짜-시간 스탬프)는 1 % 미만의 차이 만 가져야합니다.

해시를 결정할 때 게시자가 사용하는 방법을 알고있는 경우 위의 "올바른"방법을 직접 적용 할 수 있지만 메타 데이터를 확인하고 일부 휴리스틱을 적용하거나 파일의 이미지 수를 결정할 수 있습니다 페이지 수와 비교하십시오 (가까운 경우 스캔으로 구성된 문서가있을 수 있습니다). pdftext스캔 이미지에서 PDF는 또한 인식 가능한 출력을 가지고 있습니다.


I에서 작업을 기초로하는 파이썬 패키지 생성 의 bitbucket 및 / 또는에서 설치할 수 있습니다 PyPI 사용하여 pip install ruamel.pdfdouble. pdfdbl메타 데이터, 추출 된 이미지 또는 텍스트에 대해 위에서 설명한대로 스캔 하는 명령을 제공합니다 . 마킹을 필터링하지는 않지만 (아직) readme는 그것을 추가하기 위해 향상시킬 두 가지 방법을 설명합니다.

포함 된 추가 정보 :

ruamel.pdfdouble

이 패키지는 다음 pdfdbl명령을 제공합니다 .

pdfdbl scan dir1 dir2

그러면 인수로 제공된 디렉토리가 표시되고 발견 된 PDF 파일에 대해 (순서대로) 해시를 만듭니다.

  • 고유 한 경우 메타 데이터
  • 이미지 수가 이미지 인 경우
  • 본문

이것은 poppler-utils 패키지의 pdfinfo, pdfimages 및 pdftotext`를 사용할 수 있다고 가정합니다.

~/.config/pdfdbl/pdf.lst추가 스캔이 테스트되는 "데이터베이스"가 구축됩니다 .

표시 제거

에서 ruamel/pdfdouble/pdfdouble.py그들을 덜 독특하고 서로 다른 해시를 가지고 거의 동일한 파일을 PDF에 표시를 필터링 강화 될 수있는 두 가지 방법이있다.

텍스트의 경우 PdfData.filter_for_marking인수 인 문자열에서 메소드 를 표시하고 제거하여 결과를 리턴하도록 메소드 를 확장해야합니다.

스캔 된 이미지의 PdfData.process_image_and_update경우 이미지 하단 및 상단 X 라인을 잘라 내고 모든 검은 색 픽셀을 흰색으로 설정하여 회색 배경 텍스트를 제거 하여 방법 을 향상시켜야합니다. 이 함수 .update()는 필터링 된 데이터를 전달 하는 메소드를 사용하여 전달 된 해시를 업데이트해야합니다 .

제한 사항

현재 "데이터베이스"는 줄 바꿈이 포함 된 경로를 처리 할 수 ​​없습니다

이 유틸리티는 현재 Python 2.7입니다.


IP 준수 문자열 부분은 Python의 re모듈 로 대체 할 수 있습니다 .

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'

과거에는 pdfrw메타 데이터를 추출 하기 위해 파이썬 패키지 를 사용 했지만 암호화 된 pdf 파일을 처리 할 수 ​​없습니다 pdfinfo.
Anthon

2

pdftotext적어도 실제로는 텍스트를 포함하는 컬렉션의 PDF (OCR을 실행해야 함)에 더 나은 도구를 사용하여 출력을 처리 할 수있는 또 다른 기회를 제공 합니다.

(더러운) 텍스트 출력을 diff얻은 후에는 라인 별 차이가 아닌 유사성을 결정하도록 설계된 프로그램을 통해 실행하십시오 .

Perl의 String :: Similarity 또는 simhash 프로그램 (Debian에서는 사용할 수 있지만 Fedora / RHEL에서는 사용할 수 없음) 과 같은 것을 고려하십시오 .


2

PDF에는 메타 데이터가 포함되어 있으며 방금 다른 출판사의 여러 물리 관련 논문을 확인했으며 모두 "제목"속성이 있습니다. 일부의 경우 제목은 출판물의 실제 제목이며 일부의 경우 DOI 또는 유사한 식별자를 포함합니다. 어쨌든, 내가 확인한 모든 논문에는 제목이 포함되어 있으며 항상 주어진 출판물에 고유 한 것입니다.

당신이 사용할 수있는 pdftkPDF 파일의 메타 데이터에 액세스하고 사람들을 비교. 귀하의 목적을 위해 이것은 충분하고 pdftotext성능이 문제인 경우 보다 훨씬 빠릅니다 . 논문에 실제로 제목 메타 데이터가 없어야하는 경우에는 여전히로 넘어갈 수 있습니다 pdftotext.

추가 처리를 위해 모든 메타 데이터를 텍스트 파일 (또는 stdout)에 덤프하려면

pdftk <PDF> dump_data output <TEXTFILE>

추가 옵션에 대해서는 설명서를 참조하십시오.

당신이 시도하려는 경우 ImageMagick과compare문제가 원인이지만 여러 페이지를, 당신은 또한 사용할 수 있습니다 pdftk(하지만, 어쩌면 그냥 하나 하나가 충분히 비교) 단일 페이지를 잘라서 따로 그들 모두를 비교.

다음은이 접근 방식을 사용하여 여러 diff페이지 PDF에 대해 유사한 PDF 출력 을 작성하는 코드 스 니펫입니다 . https://gist.github.com/mpg/3894692


1

PDF Content Comparer 를 살펴 보셨습니까 ? 있습니다 명령 줄 옵션 이 과정을 자동화 할 수 있습니다.

차이 로그에서 어떤 종류의 논리를 실행하여 비슷한 지 확인할 수 있습니다.

PDF를 여러 파일로 일시적 으로 분할하여 그 방법으로 비교해 보지 못할 수도 있습니다 . 그래도 여전히 그런 식으로 복제본이있을 것입니다. 하나의 PDF에는 여분의 빈 페이지가 있거나 모든 후속 페이지가 완전히 다른 것으로 비교 될 수있는 무언가가있을 수 있습니다.


이 폐쇄 소스 프로그램의 가장 비싼 두 버전이 작업을 수행 할 수 있습니다. 무료 일 필요는 없지만 오픈 소스 솔루션을 선호합니다.
Jonas Stein

1

토론에 대한 겸손한 공헌 (부분 답변) :

텍스트로 변환 한 후 다음을 사용하여 (단어 차이 기반) 파일 smilarity를 ​​계산합니다.

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

(1) 다음과 같은 결과를 생성합니다

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

나는 pdf를보고 먼저을 사용하여 텍스트를 추출하려고 시도하는 스크립트를 가지고 pdftotext있지만 이것이 실패하면 (스캔 된 문서와 마찬가지로) 고스트 스크립트 를 사용 하여 여러 페이지로 스캔 된 pdf 를 일련의 png 파일로 변환 한 다음 tesseract 를 사용 하여이 시리즈를 단일 텍스트 파일로 변환합니다. 스캔 품질이 충분하면 꽤 잘 작동합니다. 파일 사이의 텍스트를 비교하는 코드를 추가하는 것은 간단하지만이 요구 사항은 없었습니다.

ghostscript와 tesseract는 모두 오픈 소스이며 명령 줄에서 작동합니다.


pdfimages고스트 스크립트를 통한 렌더링으로 얻을 수있는 추가적인 품질 손실없이 poppler 패키지에서 스캔 이미지를 직접 추출 할 수 있습니다 (원하는 OCR에 부정적인 영향을 미침).
Anthon

@Anthon은 이것을 지적 해 주셔서 감사하지만, 반드시 pdfimagesghostscript ( gs) 와 동일한 작업을 수행하고 있습니다. 즉 pdf에서 jpg / png로 이미지를 추출합니다. 왜 이것보다 더 낫 gs습니까?
gogoud

모든 스캔의 해상도가 동일하지 않은 경우 (예 : 공백 가장자리를 버린 경우) 고스트 스크립트가 렌더링하는 경우 이미지의 픽셀이 왜곡되고 이미지가 사용하는 것과 정확히 동일한 해상도로 렌더링하는 경우에만
Anthon

@Anthon 흥미롭게도, 나는 약간의 테스트를 수행했습니다. 결과는 매우 비슷하지만 gs/ tesseract(png 중간 형식) pdfimages/ / tesseract(pbm 중간 형식) 보다 약간 더 나은 것으로 보입니다 . pdfimages그래도 더 빠릅니다.
gogoud

0

나는 솔루션으로 펄을 제공 할 것입니다. CAM::PDFPDF 컨텐츠를 추출 할 수 있는 모듈 이 있습니다.

다음과 같이 조금 작동합니다.

#!/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; 
}

텍스트를 추출하여 비교할 수 있습니다.

스캔 한 문서의 경우 훨씬 어렵지만 동일한 기본 이미지를 사용 한다고 가정하면 (예 : 별도로 스캔하지 않은 경우) 다음을 사용할 수 있습니다.

#!/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;
}

소스 문서가 없기 때문에 특히 잘 테스트하지 않았습니다. 나는 이 접근법이 트릭을 수행해야 한다고 생각 합니다-실제 이미지 내용을 비교하지는 않습니다. 왜냐하면 .... 글쎄, 정말 어렵습니다. 그러나 메타 데이터에서 유사한 이미지를 인식 할 수 있어야합니다.

들어 동일한 다른 메타 데이터를 PDF 파일, 텍스트 내용을 해싱 같은 무언가 간단하고 이미지의 메타 데이터는 트릭을해야한다.


-1

recoll 이라는 Linux 응용 프로그램이 있습니다 . 작업을 수행 할 수 있지만 텍스트 레이어가있는 pdf에 대해서만 가능합니다.


2
recoll에게는 데스크톱 검색 엔진 인 것 같습니다. 중복을 찾기 위해 그것을 사용하는 방법을 볼 수 없었습니다.
Jonas Stein

1
recollpdftotextOP가 여기서 피하려고하는 PDF를 처리 하는 데 사용 합니다.
John WH Smith
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.