代码之家  ›  专栏  ›  技术社区  ›  theomega

检查PDF文件是否有效(Python)

  •  14
  • theomega  · 技术社区  · 17 年前

    我得到一个文件通过HTTP上传,需要确保它是一个pdf文件。

    我想到了以下解决方案:

    1. 检查字符串的第一个字节是否为“%PDF”。 这不是一个很好的检查,但可以防止用户意外上传其他文件。

    2. 尝试libmagic(bash上的“file”命令使用它)。 这与(1)中的检查完全相同

    3. 如果lib能够读取页面计数,那么它应该是有效的pdf。问题:我不知道python的lib可以做到这一点

    有人能想出一个解谜的办法吗?

    5 回复  |  直到 5 年前
        1
  •  22
  •   WoJ    5 年前

    更新2020

    看起来像 pdfminer.six

    ReportLab 是另一个(被我误认为死了)

    原始答案

    显然两者都不是 PyPdf 也没有 ReportLab PyPDF2 getDocumentInfo() )

    import PyPDF2
    
    with open("testfile.txt", "w") as f:
        f.write("hello world!")
    
    try:
        PyPDF2.PdfFileReader(open("testfile.txt", "rb"))
    except PyPDF2.utils.PdfReadError:
        print("invalid PDF file")
    else:
        pass
    
        2
  •  15
  •   MrTopf    17 年前

    在一个项目中,如果我需要检查一些上传文件的mime类型。我只是像这样使用file命令:

    from subprocess import Popen, PIPE
    filetype = Popen("/usr/bin/file -b --mime -", shell=True, stdout=PIPE, stdin=PIPE).communicate(file.read(1024))[0].strip()
    

    当然,您可能希望将实际命令移动到某个配置文件中,因为命令行选项在不同的操作系统(例如mac)中也有所不同。

    如果您只需要知道它是否是PDF,并且不需要处理它,我认为file命令是一个比lib更快的解决方案。当然,手工操作也是可能的,但是如果您想检查不同的类型,file命令可能会给您更大的灵活性。

        3
  •  12
  •   Van Gale    17 年前

    两者都是纯python的,因此应该易于安装,并且是跨平台的。

    使用pyPdf,它可能与执行以下操作一样简单:

    from pyPdf import PdfFileReader
    doc = PdfFileReader(file("upload.pdf", "rb"))
    

    这应该足够了,但是 doc 现在有了 documentInfo() numPages() 方法,如果要进行进一步检查。

    正如Carl回答的那样,pdftotext也是一个很好的解决方案,在非常大的文档上(特别是有许多交叉引用的文档)可能会更快。然而,由于分叉新进程等的系统开销,在小型PDF上可能会稍微慢一点。

        4
  •  2
  •   Cal Jacobson    17 年前

    如果您使用的是Linux或OS X设备,则可以使用 Pdftotext (Xpdf的一部分,发现 here )。如果您将一个非PDF文件传递给pdftotext,它肯定会对您咆哮,您可以使用commands.getstatusoutput获取输出并对其进行分析以获得这些警告。

    如果您正在寻找独立于平台的解决方案,您可能可以利用 pyPdf .

    编辑: 这并不优雅,但如果您尝试加载非PDF,pyPdf的PdfileReader似乎会抛出IOError(22)。

        5
  •  1
  •   Webucator    5 年前

    下面是一个使用 pdfminersix ,可与一起安装 pip install pdfminer.six :

    from pdfminer.high_level import extract_text
    
    def is_pdf(path_to_file):
        try:
            extract_text(path_to_file)
            return True
        except:
            return False
    

    你也可以使用 filetype pip install filetype

    import filetype
    
    def is_pdf(path_to_file):
        return filetype.guess(path_to_file).mime == 'application/pdf'
    

    这两种解决方案都不理想。

    1. filetype 解决方案是,它不会告诉您PDF本身是否正确 可读的 或者不是。它会告诉您该文件是否为PDF,但可能是损坏的PDF。
    2. 这个 pdfminer True 如果PDF文件确实可读。但它是一个很大的库,对于这样一个简单的函数来说似乎有些过分了。

    我又开始了另一个 thread here 询问如何在不使用库(或使用较小的库)的情况下检查文件是否为有效的PDF。

        6
  •  0
  •   Steve Claridge    17 年前

    “有效”是指它可以由PDF查看器显示,还是可以提取文本?它们是两种截然不同的东西。

    如果您只想检查它是否真的是一个已上载的PDF文件,那么pyPDF解决方案或类似的解决方案将起作用。

    但是,如果您想检查文本是否可以提取,那么您已经发现了整个痛苦世界!使用pdftotext将是一个简单的解决方案,在大多数情况下都能奏效,但它绝不是100%成功的。我们发现了许多PDF示例,pdftotext无法从中提取,但Java库(如iText和PDFBox)可以提取。

        7
  •  0
  •   Maged Saeed    7 年前

    我遇到了同样的问题,但没有被迫使用编程语言来管理此任务。我使用pyPDF,但对我来说效率不高,因为它无限地挂在一些损坏的文件上。

    祝你好运。

    https://sourceforge.net/projects/corruptedpdfinder/