Проверьте, является ли PDF-файл действительным (Python) - PullRequest
15 голосов
/ 18 февраля 2009

Я получаю файл через HTTP-загрузку и должен быть уверен, что это pdf-файл. Язык программирования Python, но это не имеет значения.

Я подумал о следующих решениях:

  1. Проверьте, являются ли первые байты строки "% PDF". Это не очень хорошая проверка, но предотвращает случайную загрузку других файлов.

  2. Попробуйте libmagic (команда "file" на bash использует его). Это точно такая же проверка, как 1.

  3. Возьмите библиотеку и попробуйте прочитать количество страниц в файле. Если библиотека может прочитать количество страниц, это должен быть действительный pdf. Проблема: я не знаю библиотеку для python, которая может сделать это

Значит, у кого-нибудь есть решения для библиотеки или другого трюка?

Спасибо

Ответы [ 6 ]

14 голосов
/ 18 сентября 2015

Поскольку, очевидно, ни PyPdf, ни ReportLab больше не доступны, текущее решение, которое я нашел (по состоянию на 2015 г.), заключается в использовании 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
11 голосов
/ 18 февраля 2009

Две наиболее часто используемые библиотеки PDF для Python:

Оба являются чистым питоном, поэтому должны быть простыми в установке и кроссплатформенными.

С pyPdf это было бы так же просто, как сделать:

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

Этого должно быть достаточно, но doc теперь будет иметь методы documentInfo() и numPages(), если вы хотите выполнить дополнительную проверку.

Как ответил Карл, pdftotext также является хорошим решением и, вероятно, будет быстрее при работе с очень большими документами (особенно с множеством перекрестных ссылок). Однако это может быть немного медленнее для небольших PDF-файлов из-за системных накладных расходов на создание нового процесса и т. Д.

11 голосов
/ 18 февраля 2009

В моем проекте мне нужно проверить тип 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 является более быстрым решением, чем библиотека. Делать это вручную, конечно, также возможно, но команда file дает вам больше гибкости, если вы хотите проверять разные типы.

2 голосов
/ 18 февраля 2009

Если вы используете Linux или OS X, вы можете использовать Pdftotext (часть Xpdf, найдена здесь ). Если вы передадите не PDF-файл в pdftotext, он непременно будет лаять на вас, и вы можете использовать command.getstatusoutput, чтобы получить выходные данные и проанализировать их для этих предупреждений.

Если вы ищете независимое от платформы решение, вы можете использовать pyPdf .

Редактировать: Это не элегантно, но похоже, что PdfFileReader pyPdf сгенерирует IOError (22), если вы попытаетесь загрузить не PDF.

0 голосов
/ 16 июня 2019

Я столкнулся с той же проблемой, но не был вынужден использовать язык программирования для управления этой задачей. Я использовал pyPDF, но не был эффективен для меня, поскольку он зависал бесконечно на некоторых поврежденных файлах.

Однако я нашел это программное обеспечение полезным до сих пор.

Удачи с этим.

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

0 голосов
/ 25 февраля 2009

Под действительным вы подразумеваете, что он может отображаться средством просмотра PDF или что текст может быть извлечен? Это две совершенно разные вещи.

Если вы просто хотите убедиться, что это действительно PDF-файл, который был загружен, тогда будет работать решение pyPDF или что-то подобное.

Если, однако, вы хотите проверить, может ли быть извлечен текст, вы обнаружили целый мир боли! Использование pdftotext было бы простым решением, которое работало бы в большинстве случаев, но это ни в коем случае не на 100% успешно. Мы нашли много примеров PDF-файлов, из которых pdftotext не может быть извлечен, но библиотеки Java, такие как iText и PDFBox, могут.

...