डुप्लिकेट पीडीएफ फाइलों को सामग्री द्वारा खोजें


9

कुछ पत्रिकाएं प्रत्येक डाउनलोड के लिए एक अलग पीडीएफ उत्पन्न करती हैं। उदाहरण के लिए एपीएस स्टोर समय और पीडीएफ में आईपी पते।

या हाइपर लिंक के साथ एक पेपर संस्करण है और एक पाठ संदर्भों के साथ है।

ओपन सोर्स सॉफ्टवेयर का उपयोग करके लिनक्स सिस्टम पर 90% समान सामग्री के साथ कागजात के डुप्लिकेट डाउनलोड को कैसे खोजना संभव है?

मैं एक अस्थायी निर्देशिका में पीडीएफ फाइलों को सादे पाठ में परिवर्तित करने के बारे में सोच रहा हूं pdf2txt। तब मैं सभी फ़ाइलनामों को फ़िल्टर कर सकता था जिसके diff a bपरिणामस्वरूप x रेखाएँ अधिक होती हैं। लेकिन यह बिल्कुल भी सुरुचिपूर्ण नहीं है और स्कैन किए गए प्रकाशनों के साथ विफल हो जाएगा। पत्रिकाएँ अक्सर पुराने प्रकाशनों के लिए ओसीआर पाठ प्रदान नहीं करती हैं।

मैंने compareImageMagick सूट में भी कोशिश की , लेकिन मैं इस टूल से पीडीएफ फाइलों को गुणा नहीं कर पाया।

diffpdf 2.1.1 दो फाइलों पर एक GUI में एक अच्छा काम करता है, लेकिन मैं यह पता नहीं लगा सका कि इसे कई फाइलों पर कैसे लागू किया जाए, और किसी भी ओपन सोर्स लाइसेंस के तहत हाल के संस्करण उपलब्ध नहीं हैं।


1
चूंकि उत्तरों के बीच बहुत भिन्न दृष्टिकोण हैं, इसलिए अधिक विशिष्ट होना और प्रश्न को स्पष्ट करना अच्छा हो सकता है। क्या आप अब दूसरों के बीच वैज्ञानिक पत्रों सहित विभिन्न पीडीएफ फाइलों की तुलना करने के लिए एक मजबूत तरीका ढूंढ रहे हैं या क्या आप जर्नल लेखों की तुलना करने के लिए एक कुशल, सुरुचिपूर्ण समाधान खोजने की कोशिश कर रहे हैं, जहां सिर्फ यह जांचना कि क्या शीर्षक या डीओआई मिलान पूरी तरह से पर्याप्त है।
inVader

मैं एक समान समाधान की तलाश कर रहा हूं - अब मैं md5 का उपयोग कर रहा हूं जो कि हर डाउनलोड समय और पीडीएफ में रिकॉर्ड होने पर समस्याग्रस्त है। मैं पृष्ठों के माध्यम से लूप करने के लिए एक रैपर स्क्रिप्ट के साथ इमेजमैगिक के साथ एक समाधान पर काम कर रहा हूं (और संभवतः यह पत्रिका द्वारा जोड़े गए शीर्ष लेख को छोड़ने के लिए प्रयास करें)। मुझे पूरा विश्वास है कि यह सबसे मजबूत समाधान संभव है। आप जानते हैं कि यह बहुत अच्छी तरह से काम करेगा क्योंकि यह वही विधि है जिसका उपयोग कोई व्यक्ति दो दस्तावेजों की तुलना करते समय करता है। यह दस्तावेज़ के उत्पन्न होने के तरीके पर भी पूरी तरह से स्वतंत्र है, केवल इसकी दृश्य उपस्थिति।
ओरियन

मैं यह भी कहूंगा कि एक एकल पृष्ठ की तुलना संभवतः पर्याप्त है - यह संभावना नहीं है कि एक पृष्ठ समान होने पर दो दस्तावेज़ अलग-अलग हों। नोटेशन blah.pdf[1]दस्तावेज़ से एक वांछित पेज कॉल करेगा।
ओरियन

अगर आपको वास्तव में pdfs की तुलना करने की आवश्यकता है, जहाँ एक या दोनों स्कैनिंग पर आधारित हैं, तो मुझे लगता है कि आप OCR का उपयोग करने से बच नहीं सकते हैं। यहाँ सुझाए गए कई दृष्टिकोण वास्तव में समस्या का समाधान नहीं करते हैं।
गोगौड

जवाबों:


4

चूंकि अलग-अलग प्रकाशक "अंकन" के विभिन्न तरीकों का उपयोग करते हैं, इसलिए पीडीएफ को आपको यह सुनिश्चित करने की आवश्यकता होती है कि आप चिह्नों को ध्यान में रखे बिना तुलना करते हैं।

यदि आप बार-बार एक ही PDF डाउनलोड करते हैं और जैसा कि आप सुझाव देते हैं, यह IP और / या दिनांक-समय-स्टाम्प के साथ चिह्नित किया जाता है, तो आपको पहले से डाउनलोड किए गए 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]*')।


उपरोक्त चिह्नों को हटाने और हैश उत्पन्न करने के लिए समस्या को आगे बढ़ाता है। यदि आप जानते हैं कि पीडीएफ हैश जेनरेटिंग रूटीन को लागू करते समय कहां से आता है (यानी अगर आप प्रोग्राम को डाउनलोड करते हैं), तो आप उस के आधार पर हैश जेनरेशन को फाइन-ट्यून कर सकते हैं। लेकिन इसके बिना भी हैश जेनरेशन के लिए कई संभावनाएं हैं:

  1. यदि शीर्षक और लेखक के लिए मेटाडेटा गैर-रिक्त है और "एक्रोबैट" या "पीडीएफ" जैसे गैर-विशिष्ट स्ट्रिंग्स को शामिल नहीं करता है, तो आप बस लेखक और शीर्षक जानकारी के आधार पर हैश उत्पन्न कर सकते हैं। pdfinfo -E file.pdf | grep -E '^(Author:)|(Title:) | md5sumहैश पाने के लिए उपयोग करें । आप हैश की गणना के साथ-साथ ( आउटपुट Pages:में ' ' pdfinfo) पेजों की संख्या शामिल कर सकते हैं ।
  2. यदि पिछला नियम काम नहीं करता है और पीडीएफ में चित्र हैं, तो चित्र निकालें और संयुक्त छवि डेटा पर एक हैश उत्पन्न करें। यदि छवियों में कभी भी पाद लेख या हेडर में "लाइसेन्ड टू जो यूजर" जैसे पाठ होते हैं, तो हॅश की गणना करने से पहले, एक्स या बॉटम लाइन की पट्टी को ऊपर या नीचे बनाते हैं। यदि वह चिह्न कुछ बड़े अक्षर वाले ग्रे बैकग्राउंड टेक्स्ट में है, तो यह निश्चित रूप से काम नहीं करेगा, जब तक कि आप पिक्सेल को फ़िल्टर नहीं करते हैं जो पूरी तरह से काले नहीं हैं (इसके लिए आप उपयोग कर सकते हैं imagemagick)। आप pdfimagesएक अस्थायी फ़ाइल में छवि जानकारी निकालने के लिए उपयोग कर सकते हैं ।
  3. यदि पिछले नियम काम नहीं करते हैं (क्योंकि कोई चित्र नहीं हैं) तो आप pdftextटेक्स्ट को निकालने के लिए उपयोग कर सकते हैं , मार्किंग को फ़िल्टर कर सकते हैं (यदि आप थोड़ा बहुत फ़िल्टर करते हैं, तो यह कोई समस्या नहीं है) और फिर हैश के आधार पर जेनरेट करें उस।

इसके अतिरिक्त आप तुलना कर सकते हैं कि हैश के माध्यम से मिली पुरानी फ़ाइल का फ़ाइल आकार और देखें कि क्या नई फ़ाइल के साथ कुछ मार्जिन में है। स्ट्रिंग्स (आईपी / डेट-टाइम-स्टैम्प) में संपीड़न और ifferences केवल एक प्रतिशत से कम अंतर के परिणामस्वरूप होने चाहिए।

यदि आपको पता है कि हैश का निर्धारण करते समय प्रकाशक द्वारा उपयोग की जाने वाली विधि, तो आप सीधे ऊपर की "सही" विधि को लागू कर सकते हैं, लेकिन इसके बावजूद भी आप मेटाडेटा के लिए जाँच कर सकते हैं और कुछ उत्तराधिकार को लागू कर सकते हैं, या किसी फ़ाइल में छवियों की संख्या निर्धारित कर सकते हैं। और तुलना करें कि पृष्ठों की संख्या के साथ (यदि वे पास हैं तो आपके पास संभवतः स्कैन से युक्त दस्तावेज़ है)। pdftextस्कैन की गई छवि पीडीएफ में भी एक पहचानने योग्य आउटपुट होता है।


मैं से काम करने के लिए एक आधार के रूप में एक अजगर पैकेज पर है कि बनाया bitbucket और / या से स्थापित किया जा सकता PyPI का उपयोग कर pip install ruamel.pdfdouble। यह आपको उस pdfdblकमांड के साथ प्रदान करता है जो मेटाडेटा, निकाली गई छवियों या पाठ पर ऊपर वर्णित अनुसार स्कैनिंग करता है। यह चिह्नों (अभी तक) के किसी भी फ़िल्टरिंग को नहीं करता है , लेकिन रीडमी यह वर्णन करता है कि किन (दो) तरीकों को बढ़ाने के लिए इसे जोड़ना है।

शामिल रीडमी:

ruamel.pdfdouble

यह पैकेज pdfdblकमांड प्रदान करता है :

pdfdbl scan dir1 dir2

यह तर्क के रूप में प्रदान की गई निर्देशिकाओं और नीचे दी गई पीडीएफ फाइलों के लिए चलेगा, (क्रम में) के आधार पर एक हैश बनाएं:

  • मेटाडाटा यदि अद्वितीय है
  • छवियों अगर छवियों की संख्या
  • टेक्स्ट

यह मानता है कि poppler-utils पैकेज से pdfinfo, pdfimages और pdftotext` avaialable हैं।

एक "डेटाबेस" का निर्माण किया जाता है, ~/.config/pdfdbl/pdf.lstजिसके खिलाफ आगे के स्कैन का परीक्षण किया जाता है।

चिह्नों को हटाना

में ruamel/pdfdouble/pdfdouble.pyवहाँ दो तरीकों कि पीडीएफ है कि उन्हें कम अद्वितीय बनाने के लिए और अलग अलग हैश के लिए लगभग एक ही फाइल को बनाने में चिह्नों को फिल्टर करने बढ़ाया जा सकता है कर रहे हैं।

पाठ के लिए विधि PdfData.filter_for_markingको स्ट्रिंग से निकालने और चिह्नित करने के लिए बढ़ाया जाना चाहिए जो कि इसके तर्क हैं और परिणाम लौटाते हैं।

स्कैन की गई छवियों के लिए विधि को बढ़ाने की PdfData.process_image_and_updateआवश्यकता होती है, उदाहरण के लिए छवियों को नीचे और ऊपर की एक्स लाइनों को काटकर, और सभी काले पिक्सेल को सफेद में सेट करके किसी भी ग्रे बैकग्राउंड टेक्स्ट को हटा दिया जाता है। इस फ़ंक्शन .update()को फ़िल्टर किए गए डेटा में पास करने की विधि का उपयोग करके पास किए गए हैश को अपडेट करना होगा ।

प्रतिबंध

वर्तमान "डेटाबेस" उन रास्तों को संभाल नहीं सकता है जिनमें न्यूलाइन्स शामिल हैं

यह उपयोगिता वर्तमान में केवल पायथन 2.7 है।


आईपी ​​अनुरूप स्ट्रिंगरों को पायथन के 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मेटाडेटा को निकालने के लिए अजगर पैकेज का उपयोग किया है , लेकिन वह पीडीएफ फाइलों को एन्क्रिप्ट नहीं कर सकता, जहां pdfinfoकर सकते हैं।
एंथन

2

मैं pdftotextआपके संग्रह में कम से कम पीडीएफ के लिए एक और मौका दूंगा , जिसमें वास्तव में पाठ (अन्यथा आपको ओसीआर चलाने की आवश्यकता होगी), आउटपुट को संसाधित करने के लिए एक बेहतर उपकरण का उपयोग करके।

एक बार जब आपके पास (गंदा) टेक्स्ट आउटपुट होता है, तो इसे समानताएं निर्धारित करने के लिए डिज़ाइन किए गए प्रोग्राम के माध्यम से चलाएं (बजाय diffलाइन-बाय-लाइन अंतर, जो पागलपन का एक त्वरित मार्ग होगा)।

पर्ल के स्ट्रिंग जैसे कुछ पर विचार करें :: समानता या सिम्हाश प्रोग्राम (जो डेबियन में उपलब्ध है, लेकिन फेडोरा / एचएचआर) नहीं।


2

पीडीएफ में मेटाडेटा होता है और मैंने अभी विभिन्न प्रकाशकों से भौतिकी से संबंधित कई पेपरों की जाँच की है और उन सभी में कम से कम "शीर्षक" विशेषता है। कुछ के लिए, शीर्षक प्रकाशन का वास्तविक शीर्षक है, कुछ के लिए इसमें डीओआई या समान पहचानकर्ता शामिल हैं। वैसे भी, मेरे द्वारा जांचे गए हर पेपर में शीर्षक होता है, और यह दिए गए प्रकाशन के लिए हमेशा कुछ अनूठा होता है।

आप pdftkPDFs के मेटाडेटा तक पहुँचने और उन की तुलना करने के लिए उपयोग कर सकते हैं। आपके उद्देश्य के लिए, यह निश्चित रूप से पर्याप्त होना चाहिए और pdftotextयदि प्रदर्शन एक मुद्दा है , तो यह बहुत जल्दी है । यदि कागज पर वास्तव में शीर्षक मेटाडेटा नहीं होना चाहिए तो भी आप वापस आ सकते हैं pdftotext

आगे की प्रक्रिया के उपयोग के लिए सभी मेटाडेटा को टेक्स्टफाइल (या स्टडआउट) में डंप करें

pdftk <PDF> dump_data output <TEXTFILE>

या आगे के विकल्पों के लिए मैनुअल को देखें।

यदि आप ImageMagick की कोशिश करना चाहते हैं, compareलेकिन कई पेज एक समस्या का कारण बनते हैं, तो आप pdftkएकल पृष्ठों को निकालने और उन सभी की अलग-अलग तुलना करने के लिए भी उपयोग कर सकते हैं (हो सकता है कि किसी एकल की तुलना करना पर्याप्त हो, हालांकि)।

यहाँ एक कोड स्निपेट है जो इस दृष्टिकोण का उपयोग करके diffमल्टीप्ल पीडीएफ के लिए एक समान पीडीएफ आउटपुट बनाता है : https://gist.github.com/mpg/3894692


1

क्या आपने पीडीएफ सामग्री तुलना में देखा है ? कर रहे हैं आदेश पंक्ति विकल्प है जो आप की प्रक्रिया को स्वचालित देना चाहिए।

आप अंतर लॉग पर कुछ तर्क को चला सकते हैं यह देखने के लिए बनाता है कि वे कितने समान हैं।

असफल होना कि आप अस्थायी रूप से पीडीएफ की कई फाइलों में विभाजन कर सकते हैं और उनकी तुलना इस तरह से कर सकते हैं। तुम शायद अभी भी इस तरह से डुप्लिकेट है, हालांकि। एक पीडीएफ में सिर्फ एक अतिरिक्त खाली पृष्ठ या कुछ हो सकता है जो बाद के सभी पृष्ठों को पूरी तरह से अलग होने के कारण तुलना करेगा।


हो सकता है इस बंद स्रोत कार्यक्रम के दो सबसे महंगे संस्करण काम कर सकते हैं। मैं एक खुला स्रोत समाधान पसंद करूंगा, हालांकि इसे मुफ्त में करने की आवश्यकता नहीं है।
जोनास स्टीन

1

चर्चा में विनम्र योगदान (आंशिक उत्तर):

पाठ में परिवर्तित होने के बाद, मैं निम्नलिखित (शब्द अंतर आधारित) फ़ाइल की गणना के लिए उपयोग करूंगा:

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

(२) = ९ ३


1

मेरे पास एक स्क्रिप्ट है जो एक पीडीएफ़ को देखता है और पहले पाठ का उपयोग करके निकालने की कोशिश करता है pdftotext, लेकिन अगर यह विफल रहता है (जैसा कि स्कैन किए गए दस्तावेज़ के साथ होगा), यह एक बहु-पृष्ठ स्कैन किए गए पीडीएफ को पीएनजी फ़ाइलों की एक श्रृंखला में बदलने के लिए भूत - प्रेत का उपयोग करता है और फिर इस सीरीज़ को एकल टेक्स्ट फ़ाइल में बदलने के लिए टेसरेक्ट का उपयोग करता है । यदि स्कैन पर्याप्त गुणवत्ता का है तो यह बहुत अच्छा काम करता है। फ़ाइलों के बीच पाठ की तुलना करते हुए कोड जोड़ना सीधा होगा लेकिन मुझे इसकी आवश्यकता नहीं थी।

घोस्टस्क्रिप्ट और टेसरैक्ट दोनों खुले स्रोत हैं और कमांड लाइन से काम करते हैं।


आप सीधे pdfimagesभूत के पैकेज के उपयोग से स्कैन की गई छवियों को निकाल सकते हैं, बिना किसी गुणवत्ता के अतिरिक्त नुकसान के जो आप घोस्टस्क्रिप्ट के माध्यम से प्रदान कर सकते हैं (जो किसी भी ओसीआर को नकारात्मक रूप से प्रभावित करता है जिसे आप करना चाहते हैं)।
एंथन

@ एंथन ने इसे इंगित करने के लिए धन्यवाद दिया, लेकिन निश्चित pdfimagesरूप से भूतहास्क्रिप्ट ( gs) के समान ही कर रहा है, यानी पीडीएफ से लेकर जेपीजी / पीएनजी तक के चित्र। यह इस से बेहतर क्यों है gs?
गोगुड़

जब तक कि सभी स्कैन में एक ही रिज़ॉल्यूशन नहीं होता है, तब तक घोस्टस्क्रिप्ट छवियों के पिक्सेल को विकृत कर देता है (ऐसा नहीं है, जैसे कि व्हाट्सएप किनारों को छोड़ दिया गया था) और फिर केवल अगर आप उसी रिज़ॉल्यूशन पर रेंडर करते हैं, जो चित्र का उपयोग करता है
एंथन

@ एंथन दिलचस्प, मैंने थोड़ा परीक्षण किया है। परिणाम बहुत समान हैं लेकिन ऐसा लगता है कि gs/ tesseract(png मध्यवर्ती प्रारूप) pdfimages/ tesseract(pbm मध्यवर्ती प्रारूप) की तुलना में थोड़ा बेहतर काम करता है । pdfimagesहालांकि तेज है।
गोगुड़

0

मैं एक समाधान के रूप में पर्ल की पेशकश करूंगा। वहाँ एक मॉड्यूल कहा जाता है CAM::PDFजो आपको निकालने की अनुमति देता है ... पीडीएफ सामग्री।

यह इस तरह से थोड़ा काम करता है:

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

एक लिनक्स अनुप्रयोग है, जिसे रिकॉल कहा जाता है । यह कार्य निष्पादित कर सकता है, लेकिन केवल पाठ परत के साथ pdfs के लिए।


2
मुझे recollएक डेस्कटॉप खोज इंजन लगता है। मैं देख नहीं पाया, डुप्लिकेट खोजने के लिए इसका उपयोग कैसे करना है।
जोनास स्टीन

1
recollpdftotextपीडीएफ को संभालने के लिए उपयोग करता है, जो कि ओपी यहां से बचने की कोशिश कर रहा है।
जॉन डब्ल्यूएच स्मिथ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.