発行元によってPDFの「マーキング」方法が異なるため、マーキングを考慮せずに比較する必要があります。
また、同じPDFを繰り返しダウンロードする場合に、新しい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がどこから来たかがわかっている場合(つまり、ダウンロードをプログラムで行う場合)、それに基づいてハッシュ生成を微調整できます。しかし、それがなくても、ハッシュ生成にはいくつかの可能性があります。
- タイトルと著者のメタデータが空ではなく、「Acrobat」や「PDF」などの非特定の文字列が含まれていない場合、著者とタイトルの情報のみに基づいてハッシュを生成できます。
pdfinfo -E file.pdf | grep -E '^(Author:)|(Title:) | md5sum
ハッシュを取得するために使用します。ハッシュの計算にもページ数を含めることができます(出力Pages:
には' ' pdfinfo
)。
- 前のルールが機能せず、PDFに画像が含まれている場合は、画像を抽出し、結合された画像データにハッシュを生成します。画像に「Licensed to Joe User」のようなフッターまたはヘッダーのテキストが含まれている場合は、ハッシュを計算する前に、上部または下部からX行の行を削除します。そのマーキングが大きな文字の灰色の背景テキストにある場合、完全に黒ではないピクセルを除外しない限り(これを使用できるため
imagemagick
)、これはもちろん機能しません。を使用pdfimages
して、イメージ情報を一時ファイルに抽出できます。
- 以前のルールが機能しない場合(画像がないため)
pdftext
、テキストを抽出し、マーキングをフィルターで除外し(少しだけフィルターで除外しても問題はありません)、次に基づいてハッシュを生成します。それ。
さらに、ハッシュを介して古いファイルのファイルサイズが見つかったかどうかを比較し、新しいファイルと特定のマージン内にあるかどうかを確認できます。文字列の圧縮と差異(IP / date-time-stamp)は、1%未満の差異になるだけです。
パブリッシャーがハッシュを決定するときに使用する方法がわかっている場合は、上記の「正しい」方法を直接適用できますが、それがなくてもメタデータを確認していくつかのヒューリスティックを適用するか、ファイル内の画像の数を決定できますそして、それをページ数と比較します(ページが近い場合は、スキャンで構成されたドキュメントがある可能性があります)。pdftext
スキャンした画像のPDFにも認識可能な出力があります。
作業の基礎として、bitbucket上にある、またはを使用してPyPIからインストールできるpythonパッケージを作成しましたpip install ruamel.pdfdouble
。これによりpdfdbl
、メタデータ、抽出された画像、またはテキストに対して上記のスキャンを実行するコマンドが提供されます。
マーキングのフィルタリングは(まだ)行われていませんが、readmeはそれを追加するために拡張する(2つの)メソッドを説明しています。
含まれているreadme:
ruamel.pdfdouble
このパッケージは次のpdfdbl
コマンドを提供します:
pdfdbl scan dir1 dir2
これは、引数として提供されたディレクトリをたどり、見つかったPDFファイルに対して、次の順序でハッシュを作成します。
- 一意の場合はメタデータ
- 画像数の場合は画像
- テキスト
これは、poppler-utilsパッケージのpdfinfo、pdfimages、pdftotext`が利用可能であることを前提としています。
「データベース」が構築され~/.config/pdfdbl/pdf.lst
、それに対してさらなるスキャンがテストされます。
マーキングを削除する
ではruamel/pdfdouble/pdfdouble.py
、彼らが少ないユニークにし、異なるハッシュを持って事実上同じファイルを作成するPDFにマーキングをフィルタリングするために強化することができる2つの方法があります。
テキストの場合、メソッドPdfData.filter_for_marking
を拡張して、引数である文字列からマーキングを削除し、結果を返す必要があります。
スキャンした画像の場合PdfData.process_image_and_update
、たとえば画像の下部と上部のX線を切り取り、すべての黒のピクセルを白に設定して灰色の背景テキストを削除するなど、方法を強化する必要があります。この関数.update()
は、フィルタリングされたデータを渡すメソッドを使用して、渡されたハッシュを更新する必要があります。
制限事項
現在の「データベース」は改行を含むパスを処理できません
このユーティリティは現在Python 2.7のみです。
IP準拠のstringpartsは、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'