В этой статье мы будем использовать Python для извлечения метаданных. Я покажу, как извлечь метаданные из PDF-документов, изображений, видео и аудиофайлов. Это может пригодиться в OSINT и форензике.
Еще по теме: Взлом WiFi на Python
Извлечение метаданных фото аудио и видео на Python
Итак, мы напишем программу на Python, которая будет отображать метаданные документов PDF, видео, аудио и изображений на основе расширения файла.
Извлечение метаданных PDF
Метаданные в файлах PDF представляют собой ценную информацию о документе PDF. Они включают заголовок документа, автора, дату последней модификации, дату создания, тему и многое другое. Некоторые PDF-файлы содержат больше информации, чем другие, и в этом разделе вы узнаете, как извлекать метаданные из PDF-файлов с помощью Python.
Существует множество библиотек и инструментов на Python, позволяющих достичь той же цели, но я предпочитаю использовать библиотеку pikepdf, так как она активно поддерживается. Установим ее:
1 |
$ pip install pikepdf |
Как упоминалось в статье «Взлом PDF на Python», pikepdf — это Python обертка библиотеки C++ QPDF. Импортируем ее в наш скрипт:
1 |
import sys, pikepdf |
Мы будем использовать модуль sys для получения имени файла из аргументов командной строки.
Теперь давайте создадим функцию, которая принимает имя файла PDF в качестве параметра и возвращает метаданные PDF:
1 2 3 4 5 6 |
def get_pdf_metadata(pdf_file): # Открываем pdf файл pdf = pikepdf.Pdf.open(pdf_file) # Атрибут .docinfo содержит все метаданные документа PDF return dict(pdf.docinfo) |
Результат:
1 2 3 4 5 6 7 8 9 10 11 |
/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 (в моем случае — pdfTeX).
Обратите внимание, что /ModDate и /CreationDate — это дата последней модификации и дата создания соответственно в формате даты и времени PDF.
Еще по теме: Как восстановить удаленные метаданные PDF
Извлечение метаданных из фото
Существуют бесплатные инструменты для извлечения метаданных, такие как ImageMagick или ExifTool в Linux. Но наша цель — понять, как извлечь метаданных изображения с помощью Python.
Для начала нужно установить библиотеку Pillow:
1 |
$ pip install Pillow |
Откройте новый файл Python и добавьте:
1 2 |
from PIL import Image from PIL.ExifTags import TAGS |
Учтите, что это будет работать только с файлами изображений в формате JPEG.
Создадим функцию, которая будет отвечать за извлечение метаданных изображения:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
def get_image_metadata(image_file): # Читаем данные изображения с помощью PIL image = Image.open(image_file) # Извлекаем другие основные метаданные info_dict = { "Имя файла": image.filename, "Размер изображения": image.size, "Высота изображения": image.height, "Ширина изображения": image.width, "Формат изображения": image.format, "Режим изображения": image.mode, "Анимированное изображение": getattr(image, "is_animated", False), "Количество кадров": getattr(image, "n_frames", 1) } # Извлекаем данные EXIF exifdata = image.getexif() # Итерация по всем полям данных EXIF for tag_id in exifdata: # Получаем название тега, вместо неразборчивого ID тега tag = TAGS.get(tag_id, tag_id) data = exifdata.get(tag_id) # Декодируем байты if isinstance(data, bytes): data = data.decode() # info_dict[tag] = data info_dict[tag] = data return info_dict |
Мы загрузили изображение с помощью метода Image.open(). Перед вызовом функции getexif(), библиотека Pillow предоставляет атрибуты объекта изображения, такие как размер, ширина и высота.
Проблема с переменной exifdata в том, что названия полей — это только идентификаторы, а не человеко-читаемые имена полей. Вот почему нужен словарь TAGS из модуля PIL.ExifTags, который преобразует каждый идентификатор тега в понятный текст. Это то, что мы делаем в цикле for.
Извлечение метаданных из видео и аудио
Теперь напишим код для извлечения метаданных из видео и аудио с использованием библиотек FFmpeg и tinytag:
1 |
$ pip install ffmpeg-python tinytag |
Существует множество оберток для FFmpeg на Python. Но нам больше подойдет ffmpeg-python.
Функция, которая отвечает за извлечение метаданных:
1 2 3 4 5 6 7 8 |
def get_media_metadata(media_file): # Используем команду ffprobe для извлечения всех возможных метаданных из медиа-файла ffmpeg_data = ffmpeg.probe(media_file)["streams"] tt_data = TinyTag.get(media_file).as_dict() # Объединяем оба набора данных в один словарь return {**tt_data, **ffmpeg_data} |
Метод ffmpeg.probe() использует команду ffprobe для извлечения технических метаданных, таких как продолжительность, ширина, количество каналов и многое другое.
Метод TinyTag.get() возвращает объект, содержащий аудио и видео метаданные об альбомах, треках, композиторах и т.д.
Теперь у нас есть три функции для документов PDF, изображений и видео и аудио. Давайте напишим программу, которая, в зависимости от расширения файла, будет определять, какую функцию вызывать:
1 2 3 4 5 6 7 8 9 |
if __name__ == "__main__": file = sys.argv[1] if file.endswith(".pdf"): pprint(get_pdf_metadata(file)) elif file.endswith(".jpg"): pprint(get_image_metadata(file)) else: pprint(get_media_metadata(file)) |
Если расширение файла, переданное через аргументы командной строки, заканчивается на .pdf, то это, безусловно, документ PDF. То же самое верно для файла JPEG.
В блоке else вызываем функцию get_media_metadata(), так как она поддерживает несколько расширений, таких как MP3, MP4 и многие другие медиа-расширения.
Извлечение метаданных
Сначала попробуем извлечь метаданные PDF:
1 |
$ python metadata.py bert-paper.pdf |
Результат:
1 2 3 4 5 6 7 8 9 10 |
{'/Title': pikepdf.String(""), '/ModDate': pikepdf.String("D:20190528000751Z"), '/Keywords': pikepdf.String(""), '/PTEX.Fullbanner': pikepdf.String("This is pdfTeX, Version 3.14159265-2.6-1.40.17 (TeX Live 2016) kpathsea version 6.2.2"), '/Producer': pikepdf.String("pdfTeX-1.40.17"), '/CreationDate': pikepdf.String("D:20190528000751Z"), '/Creator': pikepdf.String("LaTeX with hyperref package"), '/Trapped': pikepdf.Name("/False"), '/Author': pikepdf.String(""), '/Subject': pikepdf.String("")} |
Теперь попробуем извлечь метаданные аудиофайла:
1 |
$ python metadata.py Eurielle_Carry_Me.mp3 |
Результат:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
{'album': 'Carry Me', 'albumartist': 'Eurielle', 'artist': 'Eurielle', 'audio_offset': 4267, 'avg_frame_rate': '0/0', 'bit_rate': '128000', 'bitrate': 128.0, 'bits_per_sample': 0, 'channel_layout': 'stereo', 'channels': 2, 'codec_long_name': 'MP3 (MPEG audio layer 3)', 'codec_name': 'mp3', 'codec_tag': '0x0000', 'codec_tag_string': '[0][0][0][0]', 'codec_time_base': '1/44100', 'codec_type': 'audio', 'comment': None, 'composer': None, 'disc': '1', 'disc_total': None, 'disposition': { 'attached_pic': 0, 'clean_effects': 0, 'comment': 0, 'default': 0, 'dub': 0, 'forced': 0, 'hearing_impaired': 0, 'karaoke': 0, 'lyrics': 0, 'original': 0, 'timed_thumbnails': 0, 'visual_impaired': 0 }, 'duration': '277.838367', 'duration_ts': 3920855040, 'extra': {}, 'filesize': 4445830, 'genre': None, 'index': 0, 'r_frame_rate': '0/0', 'sample_fmt': 'fltp', 'sample_rate': '44100', 'samplerate': 44100, 'side_data_list': [{ 'side_data_type': 'Replay Gain' }], 'start_pts': 353600, 'start_time': '0.025057', 'tags': { 'encoder': 'LAME3.99r' }, 'time_base': '1/14112000', 'title': 'Carry Me', 'track': '1', 'track_total': None, 'year': '2014'} |
Теперь извлечем метаданные фотографии, сделанной на мой телефон:
1 |
$ python metadata.py image.jpg |
Результат:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
{'DateTime': '2016:11:10 19:33:22', 'ExifOffset': 226, 'Filename': 'image.jpg', 'Frames in Image': 1, 'Image Format': 'JPEG', 'Image Height': 2988, 'Image Mode': 'RGB', 'Image Size': (5312, 2988), 'Image Width': 5312, 'Image is Animated': False, 'ImageLength': 2988, 'ImageWidth': 5312, 'Make': 'samsung', 'Model': 'SM-G920F', 'Orientation': 1, 'ResolutionUnit': 2, 'Software': 'G920FXXS4DPI4', 'XResolution': 72.0, 'YCbCrPositioning': 1, 'YResolution': 72.0} |
На этом все. Теперь вы знаете, как извлекать метаданные PDF, фото, видео и аудио. В следующей статье будем использовать Python для извлечения паролей из браузера Chrome.
ПОЛЕЗНЫЕ ССЫЛКИ:
- Брут FTP с помощью ftplib на Python
- Установка и использование Python в Kali Linux
- Поиск открытых FTP с помощью ftplib на Python