PDF文件对比结果乱序问题修复及更优对比方案咨询
问题修复与优化方案
一、修复差异行顺序问题
你当前代码使用集合的symmetric_difference获取差异,而集合是无序的,这直接导致导出的差异行和原文档顺序不符。要保留原文档顺序,需改用按行顺序对比的方式,推荐使用Python标准库difflib实现逐行差异检测,它能严格保留原文本的顺序。
修改后的核心代码如下:
from difflib import SequenceMatcher # 替换原来的差异检测部分 differences_df = pd.DataFrame(columns=['pdf1_text', 'pdf2_text']) # 初始化SequenceMatcher,对比两行文本 matcher = SequenceMatcher(None, pdf1_text, pdf2_text) # 遍历对比结果,提取差异并按顺序添加到DataFrame for tag, i1, i2, j1, j2 in matcher.get_opcodes(): if tag == 'delete': # file1有,file2没有的行 for line in pdf1_text[i1:i2]: differences_df = differences_df.append( {'pdf1_text': line, 'pdf2_text': ''}, ignore_index=True ) elif tag == 'insert': # file2有,file1没有的行 for line in pdf2_text[j1:j2]: differences_df = differences_df.append( {'pdf1_text': '', 'pdf2_text': line}, ignore_index=True ) elif tag == 'replace': # 两行内容不同的情况,分别对应显示 for line1, line2 in zip(pdf1_text[i1:i2], pdf2_text[j1:j2]): differences_df = differences_df.append( {'pdf1_text': line1, 'pdf2_text': line2}, ignore_index=True )
关键说明:
difflib.SequenceMatcher会分析两个文本序列的相似性,通过get_opcodes()返回不同类型的操作(删除、插入、替换、相等)。- 我们只处理有差异的操作类型,严格按照原文档的行顺序添加差异内容,解决了顺序混乱的问题。
二、更优的PDF对比方案
1. 更可靠的文本提取工具
你当前使用的pdfminer在处理复杂布局(比如多列、图文混排)的PDF时,文本提取的行顺序可能本身就有问题。推荐使用PyMuPDF(fitz),它对PDF文本的提取准确率更高,且能更好地保留原文档的排版顺序:
import fitz def extract_pdf_text(pdf_path): doc = fitz.open(pdf_path) text_lines = [] for page in doc: # 按块提取文本,保留行结构 blocks = page.get_text("blocks") for block in blocks: # 拆分块内的文本为行 lines = block[4].split('\n') text_lines.extend([line.strip() for line in lines if line.strip()]) return text_lines # 替换原有的文本提取逻辑 pdf1_text = extract_pdf_text(pdf_files[0]) pdf2_text = extract_pdf_text(pdf_files[1])
2. 专业的PDF对比工具
如果需要更精准的对比(比如考虑PDF的视觉布局、字体、格式差异),可以使用专门的PDF对比方案:
- pdfdiff:可以直接对比两个PDF的视觉差异,生成带高亮的对比PDF文件。
- PyPDF2:结合文本提取和差异检测,适合简单的文本类PDF对比。
- 对于需要可视化差异的场景,也可以调用命令行工具(如
diff-pdf),在Python中通过subprocess调用。
3. 优化差异导出格式
可以在Excel中添加差异类型标记(比如“新增”“删除”“修改”),让结果更易读:
# 在添加行时增加类型列 differences_df = pd.DataFrame(columns=['差异类型', 'pdf1_text', 'pdf2_text']) # 示例:在delete分支添加 differences_df = differences_df.append( {'差异类型': '删除', 'pdf1_text': line, 'pdf2_text': ''}, ignore_index=True )
内容的提问来源于stack exchange,提问作者hexapod
相关产品推荐
相关产品推荐

