内容別に重複PDFファイルを探す

内容別に重複PDFファイルを探す

一部のジャーナルは、ダウンロードするたびに異なるPDFを生成します。 APSを例に挙げましょう。時間とIPアドレスをPDFとして保存します。

または、ハイパーリンクを含むハードコピーとテキスト参照を含むハードコピーがあります。

オープンソースソフトウェアを使用してLinuxシステムで90%同じ内容を含む論文の重複ダウンロードを見つける方法は?

私はPDFファイルを一時ディレクトリのプレーンテキストに変換する方法を考えてきましたpdf2txt。その後、diff a bx行を超えるすべてのファイル名をフィルタリングできます。しかし、これはまったくエレガントではなく、スキャンした出版物では失敗します。ジャーナルは通常、古い出版物についてOCRテキストを提供しません。

compareまた、ImageMagickスイートを試してみましたが、そのツールを使用して複数ページのPDFファイルを処理することはできませんでした。

違い PDF 2.1.1両方のファイルのGUIではうまく機能しますが、多くのファイルに適用する方法がわからず、最新バージョンはオープンソースライセンスに応じて利用できません。

答え1

出版社ごとに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行を削除してください。もちろん、完全に黒ではなくピクセルをフィルタリングしない限り、マークが大きな文字の灰色の背景テキスト内にある場合は機能しませんimagemagickpdfimagesを使用して画像情報を一時ファイルに抽出できます。
  3. 以前のルールが機能しない場合(画像がないため)、pdftextテキストを抽出してタグをフィルタリングしてから(あまりフィルタリングしても問題ではありません)、それを基にすることができます。

また、ハッシュによって見つかった既存のファイルのファイルサイズが一定の範囲内であるかどうかを新しいファイルと比較することもできます。文字列(IP / datetimestamp)の圧縮と違いによる違いは1%未満でなければなりません。

サイト運営者がハッシュを決定するために使用した方法を知っている場合は、上記の「正しい」方法を直接適用できますが、そうでなくてもメタデータを確認し、いくつかのヒューリスティックを適用したり、ファイル内の画像の数を確認して比較したりできます。ページ数によって異なります(ページが近い場合は、スキャンで構成された文書がある可能性が高くなります)。pdftextスキャンした画像PDFにも認識可能な出力があります。


私の仕事の基礎として、次の場所にPythonパッケージを作成しました。ビットバケットおよび/または以下からインストールできます。ピコリン酸使用pip install ruamel.pdfdouble。これはpdfdbl、メタデータ、抽出された画像、またはテキストに対して上記の検索を実行するためのコマンドを提供します。何もフィルタリングしません表示(しかし)ただし、追加情報には、このコンテンツを追加するために改善する方法(2つ)が記載されています。

含まれる追加情報ファイル:

Luamel.pdfダブル

このパッケージはpdfdbl次のコマンドを提供します。

pdfdbl scan dir1 dir2

これは引数として提供されたディレクトリを巡回し、見つかったPDFファイルのハッシュベース(順番に)を生成します。

  • メタデータ(固有の場合)
  • 画像数の場合
  • テキスト

pdfinfo、pdfimages、pdftotext` は poppler-utils パッケージで利用できると仮定します。

さらなるスキャンテスト用の「データベース」を構築してください~/.config/pdfdbl/pdf.lst

マークを削除

ruamel/pdfdouble/pdfdouble.pyPDFのタグフィルタリング機能を向上させ、タグの一意性を低下させ、ほぼ同じファイルに異なるハッシュを持たせる2つの方法があります。

PdfData.filter_for_markingテキストの場合は、文字列から引数としてトークンを削除し、結果を返すようにメソッドを拡張する必要があります。

PdfData.process_image_and_updateスキャンした画像の場合は、画像の下部と上部のX線を切り取り、すべての黒いピクセルを白に設定して灰色の背景テキストを削除するなど、方法を改善する必要があります。この関数には、.update()渡されたフィルタ処理されたデータで受信ハッシュを更新する方法が必要です。

限界

現在、「データベース」は改行文字を含むパスを処理できません。

このユーティリティは現在Python 2.7でのみ動作します。


reIP準拠の文字列部分は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'

答え2

pdftotext少なくとも実際にテキストを含むコレクションのPDFについては(そうでない場合はOCRを実行する必要があります)、より良いツールを使用して出力を処理する別の機会を与えたいと思います。

diff(汚れた)テキスト出力を取得したら、類似点を確認するように設計されたプログラムを使用して実行します(狂気の高速パスになる可能性がある1行ずつの違いではありません)。

Perlのようなものを考えてください文字列::類似性またはシムハッシュプログラム(Debianでは使用可能ですが、Fedora / RHELでは使用できません)

答え3

PDFにはメタデータが含まれています。私はいくつかの出版社のいくつかの物理学に関する論文をチェックしましたが、すべて少なくとも「タイトル」属性があります。一部の場合、タイトルは出版物の実際のタイトルであり、一部の場合はDOIまたは類似の識別子が含まれています。それにもかかわらず、私が調査したすべての論文にはタイトルが含まれており、タイトルは常にその出版物ごとに一意でした。

これを使用してpdftkPDFのメタデータにアクセスして比較できます。あなたの目的に応じて、これは間違いなく十分であり、pdftotextパフォーマンスが問題の場合よりもはるかに高速です。論文にタイトルメタデータがあってはならない場合でも、置き換えることができますpdftotext

さらなる処理のために、すべてのメタデータをテキストファイル(または標準出力)にダンプします。

pdftk <PDF> dump_data output <TEXTFILE>

その他のオプションについては、マニュアルを参照してください。

試してみたいならイメージマジシャンただし、複数のページが問題を引き起こす可能性があります。単一ページ抽出をcompare使用してすべてのページを個別に比較することもできます(単一ページを比較するだけで十分です)。pdftk

diff以下は、この方法を使用して複数ページのPDFに対してPDFに似た出力を生成するコードの一部です。https://gist.github.com/mpg/3894692

答え4

以下は議論への謙虚な貢献です(部分的な回答)。

テキストに変換されたら、次のようにファイルの類似性を計算します(単語の違いに基づいて)。

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

関連情報