使用Python和if语句解析JSON

时间:2015-05-05 20:05:31

标签: python json

这是我拥有的JSON数据:

{
  "response": {
    "status": {
      "version": "4.2",
      "code": 0,
      "message": "Success"
    },
    "artists": [
      {
        "name": "Taylor Swift",
        "foreign_ids": [
          {
            "catalog": "facebook",
            "foreign_id": "facebook:artist:19614945368"
          }
        ],
        "hotttnesss": 0.99956,
        "id": "ARS54I31187FB46721"
      },
      {
        "name": "Ed Sheeran",
        "foreign_ids": [
          {
            "catalog": "facebook",
            "foreign_id": "facebook:artist:9189674485"
          }
        ],
        "hotttnesss": 0.994265,
        "id": "ARSDWSZ122ECCB706A"
      },
      {
        "name": "Calvin Harris",
        "foreign_ids": [
          {
            "catalog": "facebook",
            "foreign_id": "facebook:artist:19366141168"
          }
        ],
        "hotttnesss": 0.990559,
        "id": "ARJRB241187FB556A3"
      },
      {
        "name": "Sam Smith",
        "foreign_ids": [
          {
            "catalog": "facebook",
            "foreign_id": "facebook:artist:313595788739120"
          }
        ],
        "hotttnesss": 0.988203,
        "id": "ARUZM8A11C8A41519C"
      },
      {
        "name": "Maroon 5",
        "foreign_ids": [
          {
            "catalog": "facebook",
            "foreign_id": "facebook:artist:5330548481"
          }
        ],
        "hotttnesss": 0.984929,
        "id": "ARF5M7Q1187FB501E8"
      },
      {
        "name": "Sia",
        "foreign_ids": [
          {
            "catalog": "facebook",
            "foreign_id": "facebook:artist:10959868407"
          }
        ],
        "hotttnesss": 0.983516,
        "id": "AR6ENUY1187B994158"
      },
      {
        "name": "David Guetta",
        "foreign_ids": [
          {
            "catalog": "facebook",
            "foreign_id": "facebook:artist:7619396355"
          }
        ],
        "hotttnesss": 0.982656,
        "id": "ARH2QI91187FB3788D"
      },
      {
        "name": "Ellie Goulding",
        "foreign_ids": [
          {
            "catalog": "facebook",
            "foreign_id": "facebook:artist:135027136641"
          }
        ],
        "hotttnesss": 0.981786,
        "id": "ARKTTJV12592CDA07F"
      },
      {
        "name": "Wiz Khalifa",
        "foreign_ids": [
          {
            "catalog": "facebook",
            "foreign_id": "facebook:artist:12138756141"
          }
        ],
        "hotttnesss": 0.978492,
        "id": "ARN0GFV1187FB508CC"
      },
      {
        "name": "Ariana Grande",
        "hotttnesss": 0.978074,
        "id": "AROHQCR13244CF7152"
      }
    ]
  }
}

我正在尝试解析“catalog”和“foreign_id”。这是我的代码:

for item in data['response']['artists']:
    for row in item['foreign_ids']:
        print row['catalog'], row['foreign_id']

结果是:

facebook facebook:artist:19614945368
facebook facebook:artist:9189674485
facebook facebook:artist:19366141168
facebook facebook:artist:313595788739120
facebook facebook:artist:5330548481
facebook facebook:artist:10959868407
facebook facebook:artist:7619396355
facebook facebook:artist:135027136641
facebook facebook:artist:12138756141

KeyError
Traceback (most recent call last)
<ipython-input-224-cbc34d6d831e> in <module>()
      1 for item in data['response']['artists']:
----> 2     for row in item['foreign_ids']:
      3         print row['catalog'], row['foreign_id']

KeyError: 'foreign_ids'

我想我知道为什么;最后一个数据行没有“foreign_ids”。我如何包含if语句来帮助我避免此错误?例如,当没有名为“foreign_ids”的数组值时,代码输出“None”。

4 个答案:

答案 0 :(得分:2)

在尝试迭代该列之前,您必须检查该列是否存在。这种方法被称为“在你跳跃之前看”。我们在这里使用get,因为它默认会返回None而不会提升KeyError

for item in data['response']['artists']:
    if item.get('foreign_ids'):
        for row in item['foreign_ids']:
            print row['catalog'], row['foreign_id']

或者,你可以使用get的默认值,它提供一个空列表来代替迭代。

for item in data['response']['artists']:
    for row in item.get('foreign_ids', []):
        print row['catalog'], row['foreign_id']

在这两种情况下,您必须检查该密钥是否存在。您所拥有的代码假定它始终存在,但绝对不是这样。

答案 1 :(得分:1)

您可以通过执行以下操作来检查密钥是否在JSON对象的该部分中:

dim lastRow as integer
lastrow = xlSheet.Range("A1").End(xlDown) 'set the value of our last used row
xlSheet.Range("A1:M" & lastRow & "").name = "xlRange1" 'apply a name to our range
lastrow = xlSheet.Range("n1").End(xlDown) 'reset our last row value
xlSheet.Range("N1:'enterlastcolumnhere'" & lastRow & "").name = "xlRange2"

xlFile.save 'save our named ranges
xlApp.Quit 'close off
Set xlApp = Nothing 



'Import File Range A 

 DoCmd.TransferSpreadsheet _ 
    transfertype:=acImport, _ 
    tablename:=strTable, _ 
    FileName:=strPath & "\" & strFile, _ 
    hasFieldNames:=False, _ 
    Range:="xlRange1" 'this should now work if we didn't get any errors when setting the named ranges

'Import File Range B 
DoCmd.TransferSpreadsheet _ 
    transfertype:=acImport, _ 
    tablename:=strTable, _ 
    FileName:=strPath & strFile, _ 
    hasFieldNames:=False, _ 
    Range:="xlRange2"

答案 2 :(得分:1)

您可以使用try / except块代替if语句(完全有效):

for item in data['response']['artists']:
    try:    
        for row in item['foreign_ids']:
            print row['catalog'], row['foreign_id']
    except KeyError as Ex:
        print "{} not found in {}".format(Ex,item)

这给出了:

...
facebook facebook:artist:7619396355
facebook facebook:artist:135027136641
facebook facebook:artist:12138756141
'foreign_ids' not found in {'id': 'AROHQCR13244CF7152', 'name': 'Ariana Grande', 'hotttnesss': 0.978074}

IMO更清洁,因为它明确承认问题并采取行动。您可以执行替代操作,而不是打印,例如log

答案 3 :(得分:0)

if 'foreign_ids' not in item:
    continue
for row in item['foreign_ids']:
....