Как разобрать этот JSON файл в Python? - PullRequest
0 голосов
/ 26 апреля 2020

У меня очень простая задача - у меня есть список файлов изображений и видео, и я хотел бы составить таблицу даты создания каждого из них, используя доступные данные EXIF. Я использую pyexiftool для фактического извлечения данных.

Я могу вытащить данные без проблем, но результирующий вывод JSON имеет очень странную форму. Каждая запись имеет одно поле, но это поле может содержать 2 или 3 или несколько битов информации.

Например, некоторые файлы изображений содержат XMP:CreateDate и EXIF:CreateDate, тогда как файлы MOV содержат 'QuickTime: CreateDate' (Я не знаю, какие поля были бы для других форматов файлов).

[{'SourceFile': '/Users/Documents/Projects/ExifData/temp/IMG_20200422_085514.JPG', 'EXIF:CreateDate': '2020:04:22 08:55:14', 'XMP:CreateDate': '2020:04:22 08:55:14'}, {'SourceFile': '/Users/Documents/Projects/ExifData/temp/IMG_20200423_091856.JPG', 'EXIF:CreateDate': '2020:04:23 09:18:57'}, {'SourceFile': '/Users/Documents/Projects/ExifData/temp/IMG_20200423_091859.JPG', 'EXIF:CreateDate': '2020:04:23 09:19:00', 'XMP:CreateDate': '2020:04:23 09:19:00'}, {'SourceFile': '/Users/Documents/Projects/ExifData/temp/MOV_0004.mp4', 'QuickTime:CreateDate': '2017:03:11 13:05:59'}, {'SourceFile': '/Users/Documents/Projects/ExifData/temp/MOV_0005.mp4', 'QuickTime:CreateDate': '2017:03:11 13:08:26'}, {'SourceFile': '/Users/Documents/Projects/ExifData/temp/MOV_0006.mp4', 'QuickTime:CreateDate': '2017:03:11 13:09:17'}, {'SourceFile': '/Users/Documents/Projects/ExifData/temp/MOV_0035.mp4', 'QuickTime:CreateDate': '2017:03:12 14:08:55'}]

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

Спасибо.

РЕДАКТИРОВАТЬ Код, который выдает этот вывод JSON, следующий:

def old_main():
    dir_name = '/Users/Documents/Projects/ExifData/temp/'
    tags = ["File Name", "CreateDate"]
    log_file = 'py_log.txt'
    file_names = getListOfFiles(dir_name)
    with exiftool.ExifTool() as e:
        metadata = e.get_tags_batch(tags, file_names)
    with open(log_file, "w") as outfile:
        json.dump(metadata, outfile)

Итак, я вставил прямой вывод метода json.dump. Метод get_tags_batch задокументирован здесь .

Если я не неправильно понял документацию для этого пакета, похоже, что вывод вовсе не JSON, а скорее просто строка?

Ценю указатели и комментарии.

Ответы [ 2 ]

1 голос
/ 26 апреля 2020

При просмотре фрагмента, который вы разместили, это list из dict. Если формат более сложный, чем этот, опубликуйте более полный пример.

Это простой способ перебора каждого элемента и установки даты на основе первого найденного поля даты.

results = []

for item in json_list:
    d = {'SourceFile': item['SourceFile']}
    date_keys = [k for k in item.keys() if 'CreateDate' in k]
    if date_keys:
        d['Date'] = item[date_keys[0]]
    else:
        d['Date'] = None
    results.append(d)
0 голосов
/ 26 апреля 2020

Причина, по которой у вас возникают проблемы при разборе этого "JSON", заключается в том, что это , а не JSON (обратите внимание на использование одинарных, а не двойных кавычек). Этот не может быть проанализирован без изменений с помощью синтаксического анализатора JSON.

Вместо этого используйте:

from ast import literal_eval

t = """[{'SourceFile': '/Users/Documents/Projects/ExifData/temp/IMG_20200422_085514.JPG', 'EXIF:CreateDate': '2020:04:22 08:55:14', 'XMP:CreateDate': '2020:04:22 08:55:14'}, {'SourceFile': '/Users/Documents/Projects/ExifData/temp/IMG_20200423_091856.JPG', 'EXIF:CreateDate': '2020:04:23 09:18:57'}, {'SourceFile': '/Users/Documents/Projects/ExifData/temp/IMG_20200423_091859.JPG', 'EXIF:CreateDate': '2020:04:23 09:19:00', 'XMP:CreateDate': '2020:04:23 09:19:00'}, {'SourceFile': '/Users/Documents/Projects/ExifData/temp/MOV_0004.mp4', 'QuickTime:CreateDate': '2017:03:11 13:05:59'}, {'SourceFile': '/Users/Documents/Projects/ExifData/temp/MOV_0005.mp4', 'QuickTime:CreateDate': '2017:03:11 13:08:26'}, {'SourceFile': '/Users/Documents/Projects/ExifData/temp/MOV_0006.mp4', 'QuickTime:CreateDate': '2017:03:11 13:09:17'}, {'SourceFile': '/Users/Documents/Projects/ExifData/temp/MOV_0035.mp4', 'QuickTime:CreateDate': '2017:03:12 14:08:55'}]"""
o = literal_eval(t)
print(o)

Отпечатки:

[{'SourceFile': '/Users/Documents/Projects/ExifData/temp/IMG_20200422_085514.JPG', 'EXIF:CreateDate': '2020:04:22 08:55:14', 'XMP:CreateDate': '2020:04:22 08:55:14'}, {'SourceFile': '/Users/Documents/Projects/ExifData/temp/IMG_20200423_091856.JPG', 'EXIF:CreateDate': '2020:04:23 09:18:57'}, {'SourceFile': '/Users/Documents/Projects/ExifData/temp/IMG_20200423_091859.JPG', 'EXIF:CreateDate': '2020:04:23 09:19:00', 'XMP:CreateDate': '2020:04:23 09:19:00'}, {'SourceFile': '/Users/Documents/Projects/ExifData/temp/MOV_0004.mp4', 'QuickTime:CreateDate': '2017:03:11 13:05:59'}, {'SourceFile': '/Users/Documents/Projects/ExifData/temp/MOV_0005.mp4', 'QuickTime:CreateDate': '2017:03:11 13:08:26'}, {'SourceFile': '/Users/Documents/Projects/ExifData/temp/MOV_0006.mp4', 'QuickTime:CreateDate': '2017:03:11 13:09:17'}, {'SourceFile': '/Users/Documents/Projects/ExifData/temp/MOV_0035.mp4', 'QuickTime:CreateDate': '2017:03:12 14:08:55'}]

Согласно manual, literal_eval:

Безопасно оценивать узел выражения или строку, содержащую литерал Python или отображение контейнера. Предоставленная строка или узел могут состоять только из следующих Python литеральных структур: строк, байтов, чисел, кортежей, списков, диктов, множеств, логических значений и None

...