编码 Python 以处理 JSON 数组不一致

Coding Python to handle JSON array inconsistencies

我一直在玩 Python 从 JSON API 抓取和解析数据。具体来说,我正在与 CTA(芝加哥交通管理局)Train Tracker API 合作。

我定期收到一个 TypeError: string indices must be integers,当多个 'train' 运行 的数组与单个 'train' 运行 存在时,我追踪到 a .单个 运行 不在 运行 的数组中。

{'ctatt':
 {'tmst': '2018-03-05T01:59:10',
 'errCd': '0',
 'errNm': None,
 'route': [{'@name': 'g'},
           {'@name': 'y',
            'train': {'rn': '030',
                     .....
                      'heading': '302'},
           {'@name': 'blue',
            'train': [{'rn': '125',
                     .....
                       'heading': '302'},
                      {'rn': '127',
                     ..... 
                       'heading': '278'},

'g' 路由没有 运行 的实例。 'y' 路线有 1 运行.

  'train': {'rn':}

'blue' 路线有多个 运行。

  'train': [{'rn': ...},{'rn': ...},{'rn': ...}]

我用来解析的代码处理缺少 运行 和多个 运行 的问题。它以 1 运行.

命中 TypeError
for train_rt in trains_data['ctatt']['route']:
    line_name = train_rt['@name']
    if train_rt.get('train', 'None') != 'None':
        for train_run in train_rt['train']:

仅处理一个不在数组中的 运行 的最佳方法是什么?

2 Yellow Line Runs in Chrome: Dev Tools: Network: Preview

1 Yellow Line Run in Chrome: Dev Tools: Network: Preview

我注意到的一个不一致之处是,如果我查询单个路由,这些路由仍然在一个包含 1 个路由的数组中。

您有两个选择:

  • 使用isinstance()
  • 显式测试列表或字典
  • 将您的访问权限放入 try:...except 并捕获 TypeError,然后继续将其视为单个元素。

选择哪一个都无关紧要(但是 can be a performance difference),选择您认为最适合您的代码的样式。

例如,如果您使用 isistance() 测试,您可以 添加 围绕单个元素的列表,这样您的其余代码就不必更改:

for train_rt in trains_data['ctatt']['route']:
    line_name = train_rt['@name']

    train_runs = train_rt.get('train', [])
    if not isinstance(train_runs, list):
        # single entry, wrap
        train_runs = [train_runs]

    for train_run in train_runs:
        # ...

请注意,如果缺少 'train' 键,上述代码将再次使用空列表进行规范化。这使您可以避免另一个 if 测试,因为现在 for 循环根本不会迭代。

如果您有这方面的支持联系人 API,我至少会报告该问题并指出他们的数据结构不一致。