Как с помощью Python извлечь метаданные PDF

Метаданные PDF‑файлов содержат полезную информацию о PDF‑документе. Они включают заголовок документа, автора, дату последнего изменения, дату создания, тему и многое другое. Некоторые файлы PDF содержат больше мета‑информации, некоторые меньше и в этом наставлении вы узнаете, как извлечь метаданные PDF с помощью Python.

В Python есть множество библиотек и утилит для выполнения одинаковых функций, но мне нравится использовать pikepdf, поскольку это активная и поддерживаемая библиотека. Установим её:

pip install pikepdf

Pikepdf — это Python‑ческая обвязка для библиотеки C++ QPDF. Импортируем его в наш скрипт, который начнем записывать в файл extract_pdf_metadata_simple.py:

import pikepdf
import sys

В довесок, для получения имени файла из аргументов командной строки будем использовать модуль sys:

# получить имя pdf-файла из командной строки
pdf_filename = sys.argv[1]

Загрузим PDF-файл с помощью библиотеки и получим метаданные:

# читать pdf-файл
pdf = pikepdf.Pdf.open(pdf_filename)
docinfo = pdf.docinfo
for key, value in docinfo.items():
    print(key, ":", value)

Теперь переменная docinfo содержит словарь метаданных документа. Вот пример исполнения:

python extract_pdf_metadata_simple.py bert-paper.pdf

Вот результат:

/Author : 
/CreationDate : D:20190528000751Z
/Creator : LaTeX with hyperref package
/Keywords :
/ModDate : D:20190528000751Z
/PTEX.Fullbanner : This is pdfTeX, Version 3.14159265-2.6-1.40.17 (TeX Live 2016) kpathsea version 6.2.2
/Producer : pdfTeX-1.40.17
/Subject :
/Title :
/Trapped : /False

Вот еще один PDF-файл:

python extract_pdf_metadata_simple.py python_cheat_sheet.pdf

И результат его анализа:

/CreationDate : D:20201002181301Z
/Creator : wkhtmltopdf 0.12.5
/Producer : Qt 4.8.7
/Title : Markdown To PDF

Как видите, не все документы имеют одинаковые поля, некоторые содержат гораздо меньше информации.

Обратите внимание, что атрибуты /ModDate и /CreationDate, дата последнего изменения и дата создания PDFсоответственно, отображаются в формате даты и времени. Если вы хотите преобразовать этот формат в формат даты и времени Python, то можно обраться к StackOverflow, что я сделал, а затем скопировав код из StackOverflow, немного его подправил для Python 3:

import pikepdf
import datetime
import re
from dateutil.tz import tzutc, tzoffset
import sys

pdf_date_pattern = re.compile(''.join([
    r"(D:)?",
    r"(?P< year>\d\d\d\d)",
    r"(?P< month>\d\d)",
    r"(?P< day>\d\d)",
    r"(?P< hour>\d\d)",
    r"(?P< minute>\d\d)",
    r"(?P< second>\d\d)",
    r"(?P< tz_offset>[+-zZ])?",
    r"(?P< tz_hour>\d\d)?",
    r"'?(?P< tz_minute>\d\d)?'?"]))

def transform_date(date_str):
    """
    Преобразование даты в формате PDF, например "D: 20120321183444 + 07'00 '", в 
    удобное для использования дату и время.
    http://www.verypdf.com/pdfinfoeditor/pdf-date-format.htm
    (Д: ГГГГММДДЧЧммССОХЧ'мм ')
    : param date_str: строка даты в формате PDF
    : return: объект datetime
    """
    global pdf_date_pattern
    match = re.match(pdf_date_pattern, date_str)
    if match:
        date_info = match.groupdict()

        for k, v in date_info.items():  # преобразовать значения
            if v is None:
                pass
            elif k == 'tz_offset':
                date_info[k] = v.lower()  # поэтому мы можем рассматривать Z как z
            else:
                date_info[k] = int(v)

        if date_info['tz_offset'] in ('z', None):  # UTC
            date_info['tzinfo'] = tzutc()
        else:
            multiplier = 1 if date_info['tz_offset'] == '+' else -1
            date_info['tzinfo'] = tzoffset(None, multiplier*(3600 * date_info['tz_hour'] + 60 * date_info['tz_minute']))

        for k in ('tz_offset', 'tz_hour', 'tz_minute'):  # больше не нужен
            del date_info[k]

        return datetime.datetime(**date_info)

# получить файл pdf из аргументов командной строки
pdf_filename = sys.argv[1]
# читать файл pdf
pdf = pikepdf.Pdf.open(pdf_filename)
docinfo = pdf.docinfo
for key, value in docinfo.items():
    if str(value).startswith("D:"):
        # pdf формат datetime, преобразовать в python datetime
        value = transform_date(str(pdf.docinfo["/CreationDate"]))
    print(key, ":", value)

В константах < year>, < month>, < day>, < hour>, < minute>, < second>, < tz_offset>, < tz_hour> и < tz_minute> не поленитесь убрать пробел после левой уголовой скобки , а то работать не будет. Сие есть издержки плагина для отображения кода...

Вот то-же самое, но с форматами datetime, преобразованными в объекты datetime Python:

/Author : 
/CreationDate : 2019-05-28 00:07:51+00:00
/Creator : LaTeX with hyperref package
/Keywords :
/ModDate : 2019-05-28 00:07:51+00:00
/PTEX.Fullbanner : This is pdfTeX, Version 3.14159265-2.6-1.40.17 (TeX Live 2016) kpathsea version 6.2.2
/Producer : pdfTeX-1.40.17
/Subject :
/Title :
/Trapped : /False

Намного лучше и надеюсь, что это краткое руководство помогло вам получить метаданные PDF‑документов с помощью Python, а моя утренняя разминка для мозгов и пальцев закончена...

По мотивам How to Extract PDF Metadata in Python

Print Friendly, PDF & Email

CC BY-NC 4.0 Как с помощью Python извлечь метаданные PDF, опубликовано К ВВ, лицензия — Creative Commons Attribution-NonCommercial 4.0 International.


Респект и уважуха

Добавить комментарий