如何用Python获取两个PDF文件的差异?
我想找出两个PDF文件之间的区别。有没有人知道有什么Python相关的工具,可以直接显示这两个PDF的不同之处?
5 个回答
我不知道你具体的使用场景,但对于使用reportlab生成PDF的脚本进行回归测试,我是这样比较PDF文件的:
- 先用ghostscript把每一页转换成图片。
- 然后用PIL把每一页的图片和标准PDF的页面图片进行对比。
比如:
im1 = Image.open(imagePath1)
im2 = Image.open(imagePath2)
imDiff = ImageChops.difference(im1, im2)
这样做在我的情况下可以有效标记出由于代码更改而引入的任何变化。
虽然这个问题已经有点时间了,但我觉得我可以为这个话题提供一些帮助。
我们有几个应用程序会生成大量的PDF文件。其中一个应用是用Python写的,最近我想写一些集成测试,来检查PDF生成是否正常。
测试PDF生成是非常困难的,因为PDF文件的规范非常复杂,而且结果不确定。即使用完全相同的数据生成两个PDF文件,它们也可能会有所不同,所以直接比较文件是不行的。
解决办法是,我们需要测试它们的外观(因为那应该是确定的!)。
在我们的案例中,PDF是通过reportlab
这个包生成的,但从测试的角度来看,这并不重要,我们只需要生成器的文件名或PDF的字节数据。我们还需要一个期望文件,里面包含一个“好的”PDF,用来和生成的PDF进行比较。
我们把PDF转换成图片,然后进行比较。这可以通过多种方式实现,但我们决定使用ImageMagick
,因为它非常灵活且成熟,几乎支持所有编程语言。对于Python 3,Wand
这个包提供了相应的支持。
测试的样子大致如下。我们去掉了一些具体实现的细节,简化了例子:
import os
from unittest import TestCase
from wand.image import Image
from app.generators.pdf import PdfGenerator
DIR = os.path.dirname(__file__)
class PdfGeneratorTest(TestCase):
def test_generated_pdf_should_match_expectation(self):
# `pdf` is the blob of the generated PDF
# If using reportlab, this is what you get calling `getpdfdata()`
# on a Canvas instance, after all the drawing is complete
pdf = PdfGenerator().generate()
# PDFs are vectorial, so we need to set a resolution when
# converting to an image
actual_img = Image(blob=pdf, resolution=150)
filename = os.path.join(DIR, 'expected.pdf')
# Make sure to use the same resolution as above
with Image(filename=filename, resolution=150) as expected:
diff = actual.compare(expected, metric='root_mean_square')
self.assertLess(diff[1], 0.01)
这里的0.01
是我们能接受的最小差异。考虑到diff[1]
的值在0到1之间变化,使用root_mean_square
这个指标,我们在这里接受与样本期望文件的比较中,所有通道的差异最多为1%。
你说的“差异”是什么意思呢?是指PDF文件里的文字不同,还是说布局有变化(比如嵌入的图形被调整了大小)?如果是文字不同,这个比较简单;但如果是布局变化,那就几乎不可能检测到,因为PDF格式非常复杂,能做的格式化方式几乎无穷无尽。
如果你想找出文字的差异,可以先把两个PDF文件转换成文本,然后用Python自带的差异比较工具来查看转换后的文本有什么不同。
这个问题涉及到如何在Python中将PDF转换为文本:Python模块用于将PDF转换为文本。
这种方法的可靠性取决于你使用的PDF生成工具。如果你用比如Adobe Acrobat和一些基于Ghostscript的PDF创建工具,从同一个Word文档生成两个PDF,可能还是会有差异,尽管源文档是完全一样的。
这是因为将源文档的信息编码成PDF的方式有很多种,每个转换工具的处理方式都不一样。通常情况下,PDF转文本的工具可能无法正确识别文本的流向,特别是在复杂的布局或表格中。