Tìm các tệp PDF trùng lặp theo nội dung


9

Một số tạp chí tạo ra một tệp PDF khác nhau cho mỗi lần tải xuống. APS ví dụ lưu trữ thời gian và địa chỉ IP trong PDF.

Hoặc có một phiên bản giấy với các liên kết siêu và một với các tham chiếu văn bản.

Làm thế nào có thể tìm thấy các bản tải xuống trùng lặp của các bài báo với 90% nội dung bằng nhau trên hệ thống linux bằng cách sử dụng phần mềm nguồn mở?

Tôi đã suy nghĩ về việc chuyển đổi các tệp PDF thành văn bản thuần trong một thư mục tạm thời với pdf2txt. Sau đó, tôi có thể lọc tất cả tên tệp có diff a bkết quả nhiều hơn x dòng. Nhưng điều này không thanh lịch chút nào và sẽ thất bại với các ấn phẩm được quét. Các tạp chí thường không cung cấp văn bản OCR cho các ấn phẩm cũ.

Tôi cũng đã thử comparetrong bộ ImageMagick, nhưng tôi không thể xử lý nhiều tệp PDF bằng công cụ này.

diffpdf 2.1.1 hoạt động tốt trong GUI trên hai tệp, nhưng tôi không thể tìm ra cách áp dụng nó trên nhiều tệp và các phiên bản gần đây không có sẵn theo bất kỳ giấy phép nguồn mở nào.


1
Vì có nhiều cách tiếp cận khác nhau giữa các câu trả lời, nên có thể tốt hơn để cụ thể hơn và làm rõ câu hỏi. Bây giờ bạn đang tìm kiếm một cách mạnh mẽ để so sánh các tệp pdf khác nhau bao gồm các bài báo khoa học giữa những người khác hoặc bạn đang cố gắng tìm một giải pháp hiệu quả, tao nhã để so sánh các bài báo, trong đó chỉ cần kiểm tra xem tiêu đề hoặc DOI có phù hợp là đủ hay không.
inVader 18/03/2015

Tôi đang tìm kiếm một giải pháp tương tự - hiện tôi đang sử dụng md5, đây là vấn đề khi mỗi lần tải xuống ghi lại thời gian và ip trong pdf. Tôi đang làm việc với một giải pháp với hình ảnh tưởng tượng với tập lệnh trình bao bọc để lặp qua các trang (và có thể cố gắng bỏ qua trang đầu tiên trong trường hợp đó là tiêu đề được thêm bởi tạp chí). Tôi rất tự tin rằng đây là giải pháp mạnh mẽ nhất có thể. Bạn biết nó sẽ hoạt động rất tốt vì đó là phương pháp tương tự mà một người sử dụng khi so sánh trực quan hai tài liệu. Nó cũng hoàn toàn độc lập về cách tạo tài liệu, chỉ có hình thức trực quan của nó.
orion

Tôi cũng nói rằng một so sánh một trang có lẽ là đủ - không chắc hai tài liệu sẽ khác nhau nếu một trang giống nhau. Ký hiệu blah.pdf[1]sẽ gọi một trang mong muốn từ tài liệu.
orion

Nếu bạn thực sự cần so sánh pdf trong đó một hoặc cả hai dựa trên quá trình quét, tôi nghĩ bạn không thể tránh sử dụng OCR. Do đó, nhiều cách tiếp cận được đề xuất ở đây không thực sự giải quyết được vấn đề.
gogoud 20/03/2015

Câu trả lời:


4

Vì các nhà xuất bản khác nhau sử dụng các phương pháp "đánh dấu" các tệp PDF khác nhau mà bạn cần đảm bảo rằng bạn so sánh mà không cần đánh dấu vào tài khoản.

Bạn cũng cần một phương pháp hiệu quả để so sánh một tệp PDF mới với tất cả các tệp PDF đã tải xuống trong trường hợp bạn liên tục tải xuống cùng một tệp PDF và nó được đánh dấu bằng IP và / hoặc dấu thời gian như bạn đề xuất. Bạn không muốn sử dụng cơ chế so sánh tốn thời gian để so sánh từng tệp PDF mới với nhiều tệp PDF đã tải xuống

Những gì bạn cần là một tiện ích loại bỏ từng dấu hiệu có thể và tạo ra một hàm băm của dữ liệu còn lại. Bạn sẽ cần giữ một bản đồ băm → ​​tên tệp, có thể ở trong một tệp đơn giản và nếu một hàm băm được tính toán đã có trong tệp bạn có một bản sao (và xóa nó hoặc làm bất cứ điều gì cần thiết) và nếu chưa băm Ở đó, bạn thêm tên băm và tên tập tin. Các tập tin sẽ trông giống như:

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

Tập tin đó nhỏ một cách sơ suất so với các tệp PDF gốc. Nếu bạn có hàng triệu tệp PDF, bạn có thể cân nhắc lưu trữ dữ liệu này trong cơ sở dữ liệu. Để hiệu quả, bạn có thể muốn bao gồm kích thước tệp và số lượng trang trong đó ( pdfinfo | egrep -E '^Pages:' | grep -Eo '[0-9]*').


Ở trên đẩy vấn đề để loại bỏ các đánh dấu và tạo ra hàm băm. Nếu bạn biết PDF đến từ đâu khi gọi thói quen tạo băm (nghĩa là nếu bạn thực hiện tải xuống theo chương trình), bạn có thể tinh chỉnh việc tạo băm dựa trên đó. Nhưng ngay cả khi không có điều đó, có một số khả năng để tạo ra hàm băm:

  1. nếu siêu dữ liệu cho tiêu đề và tác giả không trống và không bao gồm các chuỗi không cụ thể như "Acrobat" hoặc "PDF", bạn có thể tạo băm dựa trên chỉ thông tin về tác giả và tiêu đề. Sử dụng pdfinfo -E file.pdf | grep -E '^(Author:)|(Title:) | md5sumđể có được hàm băm. Bạn cũng có thể bao gồm số lượng trang để tính băm (' Pages:' trong pdfinfođầu ra).
  2. nếu quy tắc trước không hoạt động và PDF chứa hình ảnh, hãy trích xuất hình ảnh và tạo hàm băm trên dữ liệu hình ảnh kết hợp. Nếu hình ảnh từng chứa văn bản ở chân trang hoặc tiêu đề như "Được cấp phép cho người dùng Joe", hãy tước một số dòng X tạo thành trên cùng hoặc dưới cùng, trước khi tính toán hàm băm. Nếu các dấu đó nằm trong một số văn bản nền có chữ lớn màu xám thì điều này tất nhiên sẽ không hoạt động, trừ khi bạn lọc ra các pixel không hoàn toàn màu đen (mà bạn có thể sử dụng imagemagick). Bạn có thể sử dụng pdfimagesđể trích xuất thông tin hình ảnh thành một tập tin tạm thời.
  3. nếu các quy tắc trước không hoạt động (vì không có hình ảnh), bạn có thể sử dụng pdftextđể trích xuất văn bản, lọc ra đánh dấu (nếu bạn lọc ra một chút đến nhiều, đó không phải là vấn đề) và sau đó tạo ra hàm băm dựa trên cái đó.

Ngoài ra, bạn có thể so sánh nếu kích thước tệp của tệp cũ được tìm thấy qua hàm băm và xem liệu có nằm trong lề nhất định với tệp mới không. Nén và ifferences trong chuỗi (IP / ngày-tem-tem) chỉ nên dẫn đến chênh lệch ít hơn một phần trăm.

Nếu bạn biết phương pháp mà nhà xuất bản sử dụng khi xác định hàm băm, bạn có thể trực tiếp áp dụng phương pháp "đúng" ở trên, nhưng ngay cả khi không có, bạn có thể kiểm tra siêu dữ liệu và áp dụng một số phương pháp phỏng đoán hoặc xác định số lượng hình ảnh trong một tệp và so sánh với số lượng trang (nếu chúng ở gần bạn có thể có một tài liệu bao gồm các lần quét). pdftexttrên các hình ảnh PDF được quét cũng có một đầu ra dễ nhận biết.


Là cơ sở để làm việc từ tôi đã tạo ra một gói python trên bitbucket và / hoặc có thể được cài đặt từ PyPI bằng cách sử dụng pip install ruamel.pdfdouble. Điều này cung cấp cho bạn pdfdbllệnh thực hiện quét như được mô tả ở trên trên siêu dữ liệu, trích xuất hình ảnh hoặc trên văn bản. Nó không thực hiện bất kỳ bộ lọc đánh dấu nào (nhưng) , nhưng readme mô tả phương thức nào (hai) cần tăng cường để thêm vào đó.

Các readme bao gồm:

ruamel.pdfdouble

gói này cung cấp pdfdbllệnh:

pdfdbl scan dir1 dir2

Điều này sẽ đi xuống các thư mục được cung cấp dưới dạng đối số và cho các tệp PDF được tìm thấy, tạo một hàm băm dựa trên (theo thứ tự):

  • siêu dữ liệu nếu là duy nhất
  • hình ảnh nếu số lượng hình ảnh
  • bản văn

Điều này giả định rằng pdfinfo, pdfimages và pdftotext` từ gói poppler-utils là có thể sử dụng được.

Một "cơ sở dữ liệu" được xây dựng để ~/.config/pdfdbl/pdf.lstdựa vào đó các bản quét tiếp theo được kiểm tra.

Xóa dấu

Trong ruamel/pdfdouble/pdfdouble.pyđó có hai phương pháp có thể được tăng cường để lọc các dấu trong tệp PDF khiến chúng trở nên ít độc đáo hơn và làm cho hầu như các tệp giống nhau có các giá trị băm khác nhau.

Đối với văn bản, phương thức PdfData.filter_for_markingnên được mở rộng để loại bỏ và đánh dấu từ chuỗi đó là đối số của nó và trả về kết quả.

Đối với hình ảnh được quét, phương pháp PdfData.process_image_and_updatecần được tăng cường, ví dụ: bằng cách cắt các dòng X dưới cùng và trên cùng của hình ảnh, và bằng cách xóa bất kỳ văn bản nền màu xám nào bằng cách đặt tất cả các pixel đen thành màu trắng. Hàm này cần cập nhật hàm băm được truyền vào bằng cách sử dụng .update()phương thức truyền vào dữ liệu được lọc.

Những hạn chế

"Cơ sở dữ liệu" hiện tại không thể xử lý các đường dẫn có chứa dòng mới

Tiện ích này hiện chỉ là Python 2.7.


Chuỗi chuỗi phù hợp IP có thể được thay thế bằng remô-đun của Python :

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'

Trước đây tôi cũng đã sử dụng gói python pdfrwđể trích xuất siêu dữ liệu, nhưng điều đó không thể xử lý các tệp pdf được mã hóa, nơi pdfinfocó thể.
Anthon

2

Tôi sẽ cho pdftotextmột cơ hội khác, ít nhất là cho các tệp PDF trong bộ sưu tập của bạn thực sự có văn bản (nếu không bạn cần chạy OCR), sử dụng một công cụ tốt hơn để xử lý đầu ra.

Khi bạn có đầu ra văn bản (bẩn) của mình, hãy chạy nó thông qua một chương trình được thiết kế để xác định sự tương đồng (chứ không phải là diffsự khác biệt giữa từng dòng, đó sẽ là con đường nhanh chóng dẫn đến sự điên rồ).

Hãy xem xét một cái gì đó như Chuỗi của perl :: Tương tự hoặc chương trình simhash (có sẵn trong Debian nhưng không phải Fedora / RHEL).


2

Các tệp PDF chứa siêu dữ liệu và tôi chỉ kiểm tra một số tài liệu liên quan đến vật lý từ các nhà xuất bản khác nhau và tất cả chúng đều có ít nhất thuộc tính "Tiêu đề". Đối với một số người, tiêu đề là tiêu đề thực tế của ấn phẩm, đối với một số người có chứa DOI hoặc các định danh tương tự. Dù sao, mỗi bài báo tôi kiểm tra đều có tiêu đề và nó luôn là một cái gì đó độc đáo cho ấn phẩm đã cho.

Bạn có thể sử dụng pdftkđể truy cập siêu dữ liệu của các tệp PDF và so sánh chúng. Đối với mục đích của bạn, điều này chắc chắn là đủ và nhanh hơn rất nhiều so với việc pdftotexthiệu suất là một vấn đề. Trong trường hợp một bài báo thực sự không nên có siêu dữ liệu tiêu đề, bạn vẫn có thể quay lại pdftotext.

Để kết xuất tất cả siêu dữ liệu vào tệp văn bản (hoặc thiết bị xuất chuẩn) để xử lý thêm

pdftk <PDF> dump_data output <TEXTFILE>

hoặc tham khảo hướng dẫn để có thêm lựa chọn.

Nếu bạn muốn thử ImageMagick 's comparenhưng nhiều trang gây ra một vấn đề, bạn cũng có thể sử dụng pdftkđể trích xuất các trang đơn và so sánh tất cả trong số họ riêng biệt (có thể chỉ so sánh một trong những đơn là đủ, mặc dù).

Dưới đây là đoạn mã sử dụng phương pháp này để tạo diffđầu ra PDF giống như cho nhiều tệp PDF: https://gist.github.com/mpg/3894692


1

Bạn đã xem qua so sánh nội dung PDF chưa? Có các tùy chọn dòng lệnh sẽ cho phép bạn tự động hóa quá trình.

Bạn có thể chạy một số loại logic trên nhật ký khác biệt mà nó tạo ra để xem chúng giống nhau như thế nào.

Không thể tạm thời chia PDF thành nhiều tệp và so sánh chúng theo cách đó. Bạn có thể vẫn có bản sao theo cách đó, mặc dù. Một tệp PDF có thể chỉ có một trang trống thêm hoặc thứ gì đó sẽ khiến tất cả các trang tiếp theo so sánh là hoàn toàn khác nhau.


Có thể là hai phiên bản đắt nhất của chương trình nguồn đóng này có thể thực hiện công việc. Tôi muốn một giải pháp nguồn mở, mặc dù nó không cần phải miễn phí.
Jonas Stein

1

Sau một đóng góp khiêm tốn cho cuộc thảo luận (câu trả lời một phần):

Sau khi chuyển đổi thành văn bản, tôi sẽ sử dụng như sau để tính độ vui của tệp (dựa trên sự khác biệt từ):

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

(1) tạo ra một kết quả như

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

Tôi có một đoạn script nhìn vào pdf và lần đầu tiên cố gắng trích xuất văn bản bằng cách sử dụng pdftotext, nhưng nếu điều này không thành công (như với tài liệu được quét), nó sử dụng ghostscript để biến pdf quét nhiều trang thành một loạt tệp png và sau đó sử dụng tesseract để chuyển đổi chuỗi này thành một tệp văn bản. Nếu quét đủ chất lượng thì đó là một công việc khá tốt. Sẽ rất đơn giản để thêm mã so sánh văn bản giữa các tệp nhưng tôi không có yêu cầu này.

ghostscript và tesseract đều là nguồn mở và hoạt động từ dòng lệnh.


Bạn có thể trích xuất trực tiếp các hình ảnh được quét bằng cách sử dụng pdfimagestừ gói poppler mà không làm giảm chất lượng mà bạn có thể nhận được khi kết xuất qua ghostscript (điều này ảnh hưởng tiêu cực đến bất kỳ OCR nào bạn muốn làm).
Anthon

@Anthon cảm ơn bạn đã chỉ ra điều này, nhưng chắc chắn pdfimageschỉ đang làm giống như ghostscript ( gs) ở đây tức là trích xuất hình ảnh từ pdf sang jpg / png. Tại sao nó tốt hơn ở đây gs?
gogoud 20/03/2015

Kết xuất mà ghostscript làm biến dạng các pixel của hình ảnh trừ khi tất cả các lần quét có cùng độ phân giải (không phải trường hợp, ví dụ như nếu các cạnh của khoảng trắng bị loại bỏ) và sau đó chỉ khi bạn hiển thị ở cùng độ phân giải chính xác mà hình ảnh sử dụng
Anthon

@Anthon Thú vị, tôi đã làm một thử nghiệm nhỏ. Kết quả rất giống nhau nhưng có vẻ như gs/ tesseract(định dạng trung gian png) hoạt động tốt hơn một chút so với pdfimages/ tesseract(định dạng trung gian pbm). pdfimageslà nhanh hơn mặc dù.
gogoud 20/03/2015

0

Tôi sẽ cung cấp perl như một giải pháp. Có một mô-đun được gọi là CAM::PDFcho phép bạn trích xuất ... nội dung PDF.

Nó hoạt động một chút như thế này:

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

Bạn có thể trích xuất văn bản và so sánh điều đó.

Đối với các tài liệu chỉ được quét - khó hơn nhiều, nhưng giả sử chúng đang sử dụng cùng một hình ảnh cơ bản (ví dụ: chưa quét riêng chúng) thì bạn có thể sử dụng:

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

Tôi đã không kiểm tra nó đặc biệt tốt, vì tôi không có tài liệu nguồn của bạn. Tôi nghĩ rằng cách tiếp cận này nên thực hiện mẹo - mặc dù bạn không so sánh nội dung hình ảnh thực tế, bởi vì .... tốt, điều đó thực sự khó khăn. Nhưng bạn sẽ có thể nhận ra những hình ảnh tương tự từ siêu dữ liệu.

Đối với các tệp PDF giống hệt nhau với siêu dữ liệu khác nhau, thì một cái gì đó đơn giản như băm nội dung văn bản và siêu dữ liệu hình ảnh sẽ thực hiện thủ thuật.


-1

Có một ứng dụng Linux, được gọi là recoll . Nó có thể thực hiện nhiệm vụ, nhưng chỉ đối với pdf có lớp văn bản.


2
Đối với tôi recolldường như là một công cụ tìm kiếm máy tính để bàn. Tôi không thể thấy, làm thế nào để sử dụng nó để tìm bản sao.
Jonas Stein

1
recollsử dụng pdftotextđể xử lý các tệp PDF, đó là điều mà OP đang cố gắng tránh ở đây.
John WH Smith
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.