【问题标题】:I am trying to compare pdf files, and extract only the differences我正在尝试比较 pdf 文件,并仅提取差异
【发布时间】:2023-01-29 22:55:53
【问题描述】:

我在下面使用的代码帮助我比较文件并找到 CSV 文件的差异。

但是我在 CSV 文件中得到的结果是从两个文件中提取的随机行集,或者不是按照文档中的顺序。我怎样才能解决这个问题?有没有更好的方法来比较 PDF?

`from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams
from pdfminer.pdfpage import PDFPage
from io import StringIO
from itertools import chain
import pandas as pd
from time import sleep
from tqdm import tqdm


# List of pdf files to process
pdf_files = ['file1.pdf', 'file2.pdf']

# Create a list to store the text from each PDF
pdf1_text = []
pdf2_text = []

# Iterate through each pdf file
for pdf_file in tqdm(pdf_files):
    # Open the pdf file
    with open(pdf_file, 'rb') as pdf_now:
        # Extract text using pdfminer
        rsrcmgr = PDFResourceManager()
        sio = StringIO()
        codec = 'utf-8'
        laparams = LAParams()
        device = TextConverter(rsrcmgr, sio, codec=codec, laparams=laparams)
        interpreter = PDFPageInterpreter(rsrcmgr, device)
        for page in PDFPage.get_pages(pdf_now, set()):
            interpreter.process_page(page)
        text = sio.getvalue()
        text = text.split('\n')
        if pdf_file == pdf_files[0]:
            pdf1_text.append(text)
        else:
            pdf2_text.append(text)

        device.close()
        sio.close()
        sleep(20)

pdf1_text = list(chain.from_iterable(pdf1_text))
pdf2_text = list(chain.from_iterable(pdf2_text))

differences = set(pdf1_text).symmetric_difference(pdf2_text)

## Create a new dataframe to hold the differences
differences_df = pd.DataFrame(columns=['pdf1_text', 'pdf2_text'])

# Iterate through the differences and add them to the dataframe
for difference in differences:
    # Create a new row in the dataframe with the difference from pdf1 and pdf2
    differences_df = differences_df.append({'pdf1_text': difference if difference in pdf1_text else '',
                                        'pdf2_text': difference if difference in pdf2_text else ''}, ignore_index=True)

# Write the dataframe to an excel sheet
differences_df = differences_df.applymap(lambda x: x.encode('unicode_escape').decode('utf-8') if    isinstance(x, str) else x)

differences_df.to_excel('differences.xlsx', index=False, engine='openpyxl')`

【问题讨论】:

  • PDF 中的文本不需要按阅读顺序存储——根本不需要按任何特定顺序存储。因此,您将必须提取每一行,然后根据您想要的阅读顺序对每一行进行排序——可能是从左上角到右下角。所有这一切仍然处于假设之下,例如组成单词的字符实际上存储在该序列中 - 两者都不需要这样。虽然这种情况很少见,但确实会发生。使用 PyMuPDF,我将在下面的答案中展示如何快速生成排序的行列表。

标签: python python-3.x pdf pdfminer


【解决方案1】:

以下 sn-p 生成文档中已排序文本行的列表。

请注意,PyMuPDF 包支持 PDF 和六种其他文档类型(XPS、EPUB、MOBI 等)。因此,相同的代码将适用于其中任何一个。

import fitz # package PyMuPDF

def sorted_lines(filename):  # returns sorted text lines
    lines = []  # the result
    doc = fitz.open(filename)
    for page in doc:
        page_lines = []  # lines on this page
        all_text = page.get_text("dict", flags=fitz.TEXTFLAGS_TEXT)
        for block in all_text["blocks"]:
            for line in block["lines"]:
                text = "".join([span["text"] for span in line["spans"]])
                bbox = fitz.Rect(line["bbox"])  # the wrapping rectangle
                # append line text and its top-left coord
                page_lines.append((bbox.y0, bbox.x0, text))
        # sort the page lines by vertical, then by horizontal coord
        page_lines.sort(key=lambda l: (l[0], l[1]))
        lines.append(page_lines)  # append to lines of the document
    return lines

# make lists of sorted lines for the two documents
lines1 = sorted_lines(filename1)
lines2 = sorted_lines(filename2)

# now do your comparison / diff of the lines

【讨论】:

    【解决方案2】:

    即使屏幕或打印机上的内容相同,两个相同大小的 pdf 在行为上也会有不同的原因有很多。同样,两个不同的文件可以产生 100% 相同的墨水或像素布局。所以比较可能会有问题。

    这里两个文件应该输出相同的文本:-

    >pdftotext style1.pdf -
    
    Syntax Error: Unknown font tag ''
    Syntax Error (266): No font in show
    Syntax Error: Can't get Fields array<0a>
    

    但另一个副本有一个小的变化

    >pdftotext style2.pdf -
    Hello World!
    

    对于两个 PDF 的受控比较,MuPDF 或其他几个库适用于自定义查询,但是,如果您只需要对编号页面(或所有文本)进行最快的文本比较,则为 pdftotext 提取编写一行命令会更快另一个用于文件比较。然而,在这个故意说明的陷阱中,第一个文件需要进行调整才能符合要求。

    使用原始比较没有多大用处,因为除非几乎相同,否则 pdf 通常不同

    fc /A /20 style1.pdf style2.pdf && echo same || echo different
    Comparing files style1.pdf and STYLE2.PDF
    ***** style1.pdf
    %PDF-1.0
    ...
    endobj
    ***** STYLE2.PDF
    %PDF-1.0
    ...
    endobj
    *****
    
    ***** style1.pdf
    endobj
    ...
    %%EOF
    ***** STYLE2.PDF
    endobj
    ...
    %%EOF
    *****
    

    不同的

    所以在更正第一个文件之后

    >pdftotext style1(fixed).pdf && pdftotext style2.pdf
    
    >fc /A /20 style1(fixed).txt style2.txt && echo same || echo different
    Comparing files style1(fixed).txt and STYLE2.TXT
    FC: no differences encountered
    

    相同的

    然而,一切都不是看起来的那样:-
    放置方式和比例不同

    因此,测试两个文件差异的最确定的方法是:-

    对结果的一部分使用文本比较,对第二个意见使用两个文件的图形渲染。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-08
      • 2015-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-20
      相关资源
      最近更新 更多