我一直在玩Python抓取和解析来自JSON API的数据。具体来说,我正在与CTA(芝加哥交通管理局)Train Tracker API合作。
我定期收到一个TypeError: string indices must be integers
,我跟踪到的是一个多次“列车”运行的阵列,而不是单个“列车”运行。单次运行不在运行数组中。
{'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路由的数组。
答案 0 :(得分:3)
您有两种选择:
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的支持联系人,我至少会报告该问题,并指出他们的数据结构不一致。