如何使用 PyExifTool 输出 JSON

How to output JSON with PyExifTool

我是 运行 以下代码,用于输出共享驱动器上的图像和视频文件列表以及创建日期。但是,我似乎无法使 execute_json 方法正常工作。该项目的 documentation 并不广泛。

def main():
    dir_name = '/Volumes/photo/phone backup/'
    tags = ["File Name", "CreateDate"]
    log_file = '/Volumes/photo/py_log.txt'

    file_names = getListOfFiles(dir_name)
    with exiftool.ExifTool() as e:
        metadata = e.execute_json(str(e.get_tags_batch(tags, file_names)))
    f = open(log_file, "w")
    f.write(metadata)
    f.close()

我收到的错误是 AttributeError: 'list' object has no attribute 'encode'。如果我对此稍微修改一下代码,

    file_names = getListOfFiles(dir_name)
    with exiftool.ExifTool() as e:
        metadata = e.get_tags_batch(tags, file_names)
    f = open(log_file, "w")
    f.write(str(metadata))
    f.close()

生成的文件具有这种格式,

[{'SourceFile': '/Volumes/photo/phone backup/2017-05/MOV_0112.mp4', 'QuickTime:CreateDate': '2017:04:30 13:56:18'}, {'SourceFile': '/Volumes/photo/phone backup/2017-05/MOV_0174.mp4', 'QuickTime:CreateDate': '2017:06:09 06:12:47'}, {'SourceFile': '/Volumes/photo/phone backup/2017-05/MOV_0141.mp4', 'QuickTime:CreateDate': '2017:05:14 16:36:10'}

当我尝试序列化这个文件时,我得到了无效的错误 JSON。

非常感谢一些帮助,因为我完全迷路了。

我可以自己将 ' 替换为 ",但这似乎是一个极其笨拙的解决方案。

EDIT 在进一步尝试后 - 我对输出 metadata 进行了 json.dump 调用。之后用 json.load 调用它就不是问题了。但是执行以下操作,

for key in file_data:
    print (key)

此输出结果,

{'SourceFile': '/Volumes/photo/phone backup/2017-05/MOV_0112.mp4', 'QuickTime:CreateDate': '2017:04:30 13:56:18'}
{'SourceFile': '/Volumes/photo/phone backup/2017-05/MOV_0174.mp4', 'QuickTime:CreateDate': '2017:06:09 06:12:47'}

所以这根本不是 ExifTool 吐出的格式正确的 JSON 输出。它基本上只是一个大的文本转储。

我认为您可能误解了文档。如果我们查看 execute_json 方法的文档,它说:

Execute the given batch of parameters and parse the JSON output.

This method is similar to :py:meth:execute(). It automatically adds the parameter -j to request JSON output from exiftool and parses the output. The return value is a list of dictionaries, mapping tag names to the corresponding values.

这清楚地表明 exiftool 模块 解析输出 ,也就是说它读取 JSON 数据和 returns Python 数据结构列表。

同样,get_tags_batch 的文档说:

The format of the return value is the same as for :py:meth:execute_json().

所以当你这样做时...

    file_names = getListOfFiles(dir_name)
    with exiftool.ExifTool() as e:
        metadata = e.get_tags_batch(tags, file_names)
    f = open(log_file, "w")
    f.write(str(metadata))
    f.close()

...您只是将该数据的字符串表示形式写入文件(即 str(metadata) 的输出)。如果您想实际写入 JSON 数据,则需要 import json 然后:

with open(log_file, 'w') as fd:
  json.dump(metadata, log_file)

要读取此文件,我们将使用 json.load:

with open(log_file, 'r') as fd:
  metadata = json.load(fd)

这为我们提供了原始词典列表。例如,我们可以像这样迭代它:

for imageinfo in metadata:
  print('CreateDate:', imageinfo.get('EXIF:CreateDate', 'unknown'))

这是我用来测试的完整示例代码:

import exiftool
import json
import os


file_names = [f'images/{fn}' for fn in os.listdir('images')]
tags = ["File Name", "CreateDate"]
with exiftool.ExifTool() as e:
    metadata = e.get_tags_batch(tags, file_names)

with open('md.json', 'w') as fd:
    json.dump(metadata, fd)


with open('md.json', 'r') as fd:
    metadata = json.load(fd)


for imageinfo in metadata:
    print('Created: {}'.format(
        imageinfo.get('EXIF:CreateDate', 'unknown')
    ))

运行 这针对我的本地 images 目录,其中包含 7 个随机图像,结果为:

Created: 2020:01:26 15:06:12
Created: 2020:04:16 18:13:48
Created: unknown
Created: unknown
Created: 2020:01:26 15:05:54
Created: 2020:04:16 18:07:41
Created: 2020:01:26 15:07:58