ค้นหาไฟล์ PDF ซ้ำตามเนื้อหา


9

วารสารบางฉบับสร้าง PDF ที่แตกต่างกันสำหรับการดาวน์โหลดแต่ละครั้ง APS เช่นเก็บเวลาและที่อยู่ IP ใน PDF

หรือมีรุ่นกระดาษที่มีการเชื่อมโยงหลายมิติและรุ่นที่มีการอ้างอิงข้อความ

เป็นไปได้อย่างไรที่จะค้นหาการดาวน์โหลดเอกสารที่มีเนื้อหาเท่ากัน 90% บนระบบ linux โดยใช้ซอฟต์แวร์โอเพ่นซอร์ส

ฉันได้รับความคิดเกี่ยวกับการแปลงไฟล์ PDF pdf2txtไปยังข้อความธรรมดาในไดเรกทอรีชั่วคราว จากนั้นฉันสามารถกรองชื่อไฟล์ทั้งหมดที่ให้diff a bผลลัพธ์มากกว่าเส้น x แต่นี่ไม่ได้สวยงามเลยและจะล้มเหลวกับสิ่งพิมพ์ที่สแกน วารสารมักจะไม่ให้ข้อความ OCR สำหรับสิ่งพิมพ์เก่า

ฉันลองcompareในชุด ImageMagick ด้วย แต่ฉันไม่สามารถจัดการไฟล์ PDF หลายไฟล์ได้ด้วยเครื่องมือนี้

diffpdf 2.1.1ทำงานได้ดีใน GUI บนสองไฟล์ แต่ฉันไม่สามารถหาวิธีนำไปใช้กับไฟล์จำนวนมากได้และเวอร์ชันล่าสุดไม่สามารถใช้ได้ภายใต้ใบอนุญาตโอเพนซอร์สใด ๆ


1
เนื่องจากมีวิธีการที่แตกต่างกันมากในบรรดาคำตอบมันอาจจะดีกว่าที่จะเจาะจงและชี้แจงคำถาม ตอนนี้คุณกำลังมองหาวิธีที่มีประสิทธิภาพในการเปรียบเทียบไฟล์ PDF ที่แตกต่างกันรวมถึงเอกสารทางวิทยาศาสตร์ของคนอื่น ๆ หรือคุณกำลังพยายามหาวิธีที่มีประสิทธิภาพและสวยงามในการเปรียบเทียบบทความวารสารที่เพิ่งตรวจสอบว่าชื่อหรือ DOI ตรงกันหรือไม่
inVader

ฉันกำลังมองหาวิธีการแก้ปัญหาที่คล้ายกัน - ตอนนี้ฉันกำลังใช้ md5 ซึ่งเป็นปัญหาเมื่อทุกครั้งที่มีการดาวน์โหลดบันทึกและ ip ในรูปแบบ pdf ฉันกำลังแก้ปัญหาด้วย imagemagick ด้วยสคริปต์ wrapper เพื่อวนซ้ำหน้าต่างๆ (และอาจพยายามข้ามหน้าแรกในกรณีที่เป็นส่วนหัวที่เพิ่มโดยเจอร์นัล) ฉันมั่นใจมากว่านี่เป็นคำตอบที่มีประสิทธิภาพที่สุด คุณรู้ว่ามันจะทำงานได้ดีเพราะมันเป็นวิธีเดียวกับที่คนใช้เมื่อเปรียบเทียบเอกสารสองภาพ นอกจากนี้ยังเป็นอิสระอย่างสมบูรณ์เกี่ยวกับวิธีการสร้างเอกสารเฉพาะรูปลักษณ์ภายนอกเท่านั้น
orion

ฉันก็บอกว่าการเปรียบเทียบหน้าเดียวอาจจะเพียงพอ - มันไม่น่าเป็นไปได้ที่เอกสารสองฉบับจะแตกต่างกันหากหน้าเดียวเหมือนกัน เอกสารblah.pdf[1]จะเรียกหน้าที่ต้องการจากเอกสาร
orion

หากคุณต้องการเปรียบเทียบไฟล์ PDF ที่หนึ่งหรือทั้งสองอิงกับการสแกนฉันคิดว่าคุณไม่สามารถหลีกเลี่ยงการใช้ OCR ได้ แนวทางที่แนะนำจำนวนมากที่นี่จึงไม่ได้แก้ปัญหาจริงๆ
gogoud

คำตอบ:


4

เนื่องจากผู้เผยแพร่ที่แตกต่างกันใช้วิธีการ "ทำเครื่องหมาย" ที่แตกต่างกันคุณจำเป็นต้องตรวจสอบให้แน่ใจว่าคุณเปรียบเทียบโดยไม่คำนึงถึงการทำเครื่องหมาย

คุณต้องมีวิธีที่มีประสิทธิภาพในการเปรียบเทียบ PDF ใหม่กับ PDF ที่ดาวน์โหลดไปแล้วทั้งหมดในกรณีที่คุณดาวน์โหลด PDF ซ้ำ ๆ ซ้ำ ๆ และมันถูกทำเครื่องหมายด้วย IP และ / หรือประทับวันที่ตามเวลาที่คุณแนะนำ คุณไม่ต้องการใช้กลไกการเปรียบเทียบที่เสียเวลาซึ่งเปรียบเทียบแต่ละ PDF ใหม่กับ PDF ที่ดาวน์โหลดไปแล้วจำนวนมาก

สิ่งที่คุณต้องการคือยูทิลิตี้ที่แยกแต่ละเครื่องหมายที่เป็นไปได้และสร้างแฮชของข้อมูลที่เหลือ คุณจะต้องเก็บ hash →ชื่อไฟล์แม็พซึ่งสามารถอยู่ในไฟล์แบบง่ายและหากแฮชที่คำนวณอยู่แล้วในไฟล์ที่คุณมีซ้ำ (และลบหรือทำสิ่งที่จำเป็น) และหากแฮยังไม่ได้ คุณเพิ่มแฮชและชื่อไฟล์ที่นั่น ไฟล์จะมีลักษณะดังนี้:

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 / date-time-time) จะทำให้เกิดความแตกต่างน้อยกว่าหนึ่งเปอร์เซ็นต์เท่านั้น

หากคุณทราบวิธีการที่ผู้เผยแพร่โฆษณาใช้ในการพิจารณาแฮชคุณสามารถใช้วิธีการ "ถูกต้อง" ข้างต้นได้โดยตรง แต่ถึงแม้จะไม่มีคุณก็สามารถตรวจสอบข้อมูลเมตาและใช้การวิเคราะห์พฤติกรรมหรือกำหนดจำนวนภาพในไฟล์ และเปรียบเทียบกับจำนวนหน้า (ถ้าพวกเขาอยู่ใกล้คุณอาจมีเอกสารที่ประกอบด้วยการสแกน) pdftextบนรูปภาพที่สแกน PDF ยังมีเอาต์พุตที่รู้จัก


เป็นพื้นฐานในการทำงานจากที่ผมสร้างแพคเกจหลามที่อยู่บนbitbucketและ / หรือสามารถติดตั้งจากPyPIpip install ruamel.pdfdoubleใช้ สิ่งนี้ช่วยให้คุณมีpdfdblคำสั่งที่ทำการสแกนตามที่อธิบายไว้ด้านบนในเมทาดาทา, รูปภาพที่แตกแล้วหรือข้อความ มันไม่ได้ทำการกรองเครื่องหมาย (แต่) readme อธิบายถึงวิธีการ (สอง) ในการปรับปรุงเพื่อเพิ่ม

รวม readme:

ruamel.pdfdouble

แพคเกจนี้ให้pdfdblคำสั่ง:

pdfdbl scan dir1 dir2

สิ่งนี้จะแสดงไดเรกทอรีที่มีให้เป็นอาร์กิวเมนต์และสำหรับไฟล์ PDF ที่พบให้สร้างแฮชตาม (ตามลำดับ):

  • ข้อมูลเมตาถ้าไม่ซ้ำกัน
  • ภาพถ้าจำนวนภาพ
  • ข้อความ

สิ่งนี้ถือว่า pdfinfo, pdfimages และ pdftotext` จากแพ็คเกจ poppler-utils นั้นหาได้

"ฐานข้อมูล" ถูกสร้างขึ้น~/.config/pdfdbl/pdf.lstเพื่อทดสอบการสแกนเพิ่มเติม

การลบเครื่องหมาย

ในruamel/pdfdouble/pdfdouble.pyมีสองวิธีที่สามารถปรับปรุงเพื่อกรองเครื่องหมายใน PDF ที่ทำให้พวกเขาไม่ซ้ำกันน้อยลงและทำให้ไฟล์เดียวกันแทบจะมีแฮชที่แตกต่างกัน

สำหรับข้อความPdfData.filter_for_markingควรขยายวิธีการเพื่อลบและทำเครื่องหมายจากสตริงที่เป็นอาร์กิวเมนต์และส่งคืนผลลัพธ์

สำหรับภาพที่สแกนPdfData.process_image_and_updateต้องมีการปรับปรุงวิธีการเช่นตัดส่วนล่างของภาพและเส้นบนสุด X ออกและด้วยการลบข้อความพื้นหลังสีเทาโดยการตั้งค่าพิกเซลสีดำทั้งหมดเป็นสีขาว ฟังก์ชันนี้จำเป็นต้องอัพเดตแฮชที่ส่งผ่านโดยใช้.update()วิธีการส่งผ่านข้อมูลที่กรอง

ข้อ จำกัด

"ฐานข้อมูล" ปัจจุบันไม่สามารถจัดการเส้นทางที่มีการขึ้นบรรทัดใหม่ได้

ยูทิลิตี้นี้ปัจจุบันคือ Python 2.7 เท่านั้น


IP ที่สอดคล้องกับ stringparts สามารถถูกแทนที่ด้วยreโมดูลของ 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'

ในอดีตที่ผ่านมาฉันใช้แพ็คเกจหลามpdfrwเพื่อแยกข้อมูลเมตาเช่นกัน แต่นั่นไม่สามารถจัดการไฟล์ PDF ที่เข้ารหัสได้ซึ่งpdfinfoสามารถทำได้
Anthon

2

ฉันจะให้pdftotextโอกาสอีกอย่างน้อยที่สุดสำหรับ PDF ในคอลเล็กชันของคุณที่มีข้อความจริง (ไม่เช่นนั้นคุณจะต้องเรียกใช้ OCR) โดยใช้เครื่องมือที่ดีกว่าในการประมวลผลเอาต์พุต

เมื่อคุณมีเอาต์พุตข้อความ (สกปรก) ให้รันผ่านโปรแกรมที่ออกแบบมาเพื่อกำหนดความคล้ายคลึงกัน (แทนที่จะเป็นdiffความแตกต่างของบรรทัดต่อบรรทัดซึ่งจะเป็นเส้นทางที่รวดเร็วไปสู่ความวิกลจริต)

ลองพิจารณาบางอย่างของString :: Similarityหรือโปรแกรมsimhash (ซึ่งมีให้ในภาษา Debian แต่ไม่ใช่ Fedora / RHEL)


2

PDF มีข้อมูลเมตาและฉันเพิ่งตรวจสอบเอกสารเกี่ยวกับฟิสิกส์จากผู้เผยแพร่ที่แตกต่างกันและอย่างน้อยพวกเขาก็มีแอตทริบิวต์ "ชื่อ" อย่างน้อย สำหรับบางคนชื่อเป็นชื่อเรื่องจริงของสิ่งพิมพ์สำหรับบางรายการมี DOI หรือตัวระบุที่คล้ายกัน อย่างไรก็ตามกระดาษทุกเล่มที่ฉันตรวจสอบมีชื่อและมันก็เป็นสิ่งที่ไม่ซ้ำกันสำหรับสิ่งพิมพ์ที่กำหนด

คุณสามารถใช้pdftkเพื่อเข้าถึงข้อมูลเมตาของ PDF และเปรียบเทียบ สำหรับวัตถุประสงค์ของคุณการดำเนินการนี้ควรเพียงพอและเร็วกว่าpdftotextการปฏิบัติงานจริง pdftotextในกรณีที่เป็นกระดาษมันไม่ควรจะมีเมตาดาต้าชื่อคุณอาจจะยังคงถอยกลับไปเพื่อ

หากต้องการดัมพ์ข้อมูลเมตาทั้งหมดไปยังเท็กซ์ไฟล์ (หรือ stdout) สำหรับการประมวลผลเพิ่มเติมให้ใช้

pdftk <PDF> dump_data output <TEXTFILE>

หรือดูคู่มือสำหรับตัวเลือกเพิ่มเติม

ถ้าคุณอยากจะลองImageMagick 's compareแต่หลาย ๆ หน้าทำให้เกิดปัญหาคุณยังสามารถใช้pdftkในการดึงหน้าเดียวและเปรียบเทียบทั้งหมดของพวกเขาต่างหาก (อาจจะเป็นเพียงแค่การเปรียบเทียบหนึ่งเดียวก็พอแม้ว่า)

นี่คือข้อมูลโค้ดที่ใช้วิธีการนี้ในการสร้างdiffเอาต์พุต PDF ที่เหมือนกันสำหรับ PDF หลายหน้า: https://gist.github.com/mpg/3894692


1

คุณดูเป็นPDF Content Comparerหรือไม่ มีตัวเลือกบรรทัดคำสั่งที่จะให้คุณทำกระบวนการให้เป็นอัตโนมัติ

คุณสามารถเรียกใช้ตรรกะบางอย่างในบันทึกความแตกต่างที่สร้างขึ้นเพื่อดูว่าคล้ายกันอย่างไร

ความล้มเหลวที่คุณอาจลองแบ่งไฟล์ PDF ออกเป็นหลายไฟล์ชั่วคราวและทำการเปรียบเทียบด้วยวิธีดังกล่าว คุณอาจจะยังคงมีวิธีที่ซ้ำกันแม้ว่า PDF หนึ่งไฟล์อาจมีหน้าว่างพิเศษหรือสิ่งที่ทำให้หน้าถัดไปทั้งหมดเปรียบเทียบว่าแตกต่างอย่างสิ้นเชิง


อาจเป็นเวอร์ชันปิดที่แพงที่สุดของโปรแกรมซอร์สนี้สามารถทำงานได้ ฉันต้องการโซลูชันโอเพนซอร์ซแม้ว่าจะไม่จำเป็นต้องเสียค่าใช้จ่าย
Jonas Stein

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

(2) = 93


1

ฉันมีสคริปต์ซึ่งดูเป็น pdf และพยายามดึงข้อความโดยใช้ครั้งแรกpdftotextแต่ถ้าสิ่งนี้ล้มเหลว (เช่นเดียวกับเอกสารที่สแกน) จะใช้ghostscriptเพื่อแปลงไฟล์ PDF ที่สแกนหลายหน้าเป็นชุดไฟล์ png จากนั้น ใช้tesseractเพื่อแปลงชุดนี้เป็นไฟล์ข้อความเดียว หากการสแกนมีคุณภาพเพียงพอจะเป็นการดีมาก มันจะตรงไปตรงมาเพื่อเพิ่มรหัสเปรียบเทียบข้อความระหว่างไฟล์ แต่ฉันไม่ได้มีข้อกำหนดนี้

ghostscript และ tesseract เป็นทั้งโอเพ่นซอร์สและทำงานจากบรรทัดคำสั่ง


คุณสามารถดึงภาพที่สแกนออกมาได้โดยตรงpdfimagesจากแพ็คเกจ poppler โดยไม่สูญเสียคุณภาพที่คุณสามารถทำได้ด้วยการเรนเดอร์ผ่าน ghostscript (ซึ่งมีผลเสียต่อ OCR ใด ๆ ที่คุณต้องการ)
Anthon

@ ขอบคุณที่ชี้ให้เห็น แต่แน่นอนว่าpdfimagesทำเช่นเดียวกันกับ ghostscript ( gs) นี่คือการดึงภาพจาก pdf ไปยัง jpg / png ทำไมเรื่องนี้ถึงดีกว่าgs?
gogoud

การเรนเดอร์ที่ ghostscript จะบิดเบือนพิกเซลของรูปภาพยกเว้นว่าการสแกนทั้งหมดจะมีความละเอียดเท่ากัน (ไม่ใช่กรณีเช่นถ้าขอบช่องว่างถูกทิ้ง) และจากนั้นก็ต่อเมื่อคุณแสดงที่ความละเอียดเดียวกันกับที่ภาพใช้
Anthon

@ อันที่น่าสนใจฉันได้ทำการทดสอบเล็กน้อย ผลลัพธ์คล้ายกันมาก แต่ดูเหมือนว่าgs/ tesseract(รูปแบบสื่อกลาง png) ทำงานได้ดีกว่าpdfimages/ tesseract(รูปแบบสื่อกลาง pbm) เล็กน้อย pdfimagesแม้ว่าจะเร็วกว่า
gogoud

0

ฉันจะเสนอ perl เป็นวิธีแก้ปัญหา มีโมดูลที่เรียกว่าCAM::PDFซึ่งให้คุณสามารถดึง ... เนื้อหา 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

มีการประยุกต์ใช้ลินุกซ์ที่เรียกว่าเป็นrecoll สามารถทำงานได้ แต่เฉพาะไฟล์ PDF ที่มีเลเยอร์ข้อความ


2
สำหรับฉันrecollดูเหมือนว่าจะเป็นเครื่องมือค้นหาบนเดสก์ท็อป ฉันไม่เห็นวิธีใช้เพื่อค้นหารายการที่ซ้ำกัน
Jonas Stein

1
recollใช้pdftotextในการจัดการ PDF ซึ่งเป็นสิ่งที่ OP พยายามหลีกเลี่ยงที่นี่
John WH Smith
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.