JSON sub for循环生成KeyError,但密钥存在

时间:2016-10-08 11:40:31

标签: python json list for-loop dictionary

我正在尝试将下面的JSON输出添加到字典中,以保存到SQL数据库中。

{'Parkirisca': [
    {    
    'ID_Parkirisca': 2,
    'zasedenost': {
                   'Cas': '2016-10-08 13:17:00',
                   'Cas_timestamp': 1475925420,
                   'ID_ParkiriscaNC': 9,
                   'P_kratkotrajniki': 350
                  }
    }
]}

我目前正在使用以下代码将值添加到字典中:

import scraperwiki
import json
import requests
import datetime
import time
from pprint import pprint

html = requests.get("http://opendata.si/promet/parkirisca/lpt/")

data = json.loads(html.text)

for carpark in data['Parkirisca']:

    zas = carpark['zasedenost']
    free_spaces = zas.get('P_kratkotrajniki')
    last_updated = zas.get('Cas_timestamp')

    parking_type = carpark.get('ID_Parkirisca')
    if parking_type == "Avtomatizirano":
        is_automatic = "Yes"
    else:
        is_automatic = "No"

    scraped = datetime.datetime.fromtimestamp(time.time()).strftime('%Y-%m-%d %H:%M:%S')

    savetodb = {
    'scraped': scraped,
    'id': carpark.get("ID_Parkirisca"),
    'total_spaces': carpark.get("St_mest"),
    'free_spaces': free_spaces,
    'last_updated': last_updated,
    'is_automatic': is_automatic,
    'lon': carpark.get("KoordinataX_wgs"), 
    'lat': carpark.get("KoordinataY_wgs")
    }

    unique_keys = ['id']

    pprint savetodb

然而,当我运行它时,它会卡在for zas in carpark["zasedenost"]并输出以下错误:

Traceback (most recent call last):
File "./code/scraper", line 17, in <module>
    for zas in carpark["zasedenost"]:
KeyError: 'zasedenost'

我一直认为zas实际上现在是一个字符串,而不是字典,但我是Python和JSON的新手,所以不知道要搜索什么来获取解。我也在这里搜索Stack Overflow上的KeyErrror when key exist个问题,但是他们没有帮助,我相信这可能是因为这是一个子循环。

更新:现在,当我用双引号替换单引号时,我收到以下错误:

Traceback (most recent call last):
File "./code/scraper", line 17, in <module>
    free_spaces = zas.get('P_kratkotrajniki')
AttributeError: 'unicode' object has no attribute 'get'

1 个答案:

答案 0 :(得分:1)

我修改了你的代码:

  1. 添加了必需的导入。
  2. 修正了pprint savetodb行,它不是有效的Python。
  3. 没有尝试迭代carpark['zasedenost']
  4. 然后我在pprint循环中添加了另一个for语句,以查看carpark发生时KeyError中的内容。从那里,错误很明显。 (并非JSON中数组中的所有元素都包含'zasedenost'键。)

    这是我使用的代码:

    import datetime
    import json
    from pprint import pprint
    import time
    
    import requests
    
    html = requests.get("http://opendata.si/promet/parkirisca/lpt/")
    
    data = json.loads(html.text)
    
    for carpark in data['Parkirisca']:
        pprint(carpark)
        zas = carpark['zasedenost']
        free_spaces = zas.get('P_kratkotrajniki')
        last_updated = zas.get('Cas_timestamp')
    
        parking_type = carpark.get('ID_Parkirisca')
        if parking_type == "Avtomatizirano":
            is_automatic = "Yes"
        else:
            is_automatic = "No"
    
        scraped = datetime.datetime.fromtimestamp(time.time()).strftime('%Y-%m-%d %H:%M:%S')
    
        savetodb = {
            'scraped': scraped,
            'id': carpark.get("ID_Parkirisca"),
            'total_spaces': carpark.get("St_mest"),
            'free_spaces': free_spaces,
            'last_updated': last_updated,
            'is_automatic': is_automatic,
            'lon': carpark.get("KoordinataX_wgs"), 
            'lat': carpark.get("KoordinataY_wgs")
        }
    
        unique_keys = ['id']
    
        pprint(savetodb)
    

    这里是KeyError发生的迭代输出:

    {u'A_St_Mest': None,
     u'Cena_dan_Eur': None,
     u'Cena_mesecna_Eur': None,
     u'Cena_splosno': None,
     u'Cena_ura_Eur': None,
     u'ID_Parkirisca': 7,
     u'ID_ParkiriscaNC': 72,
     u'Ime': u'P+R Studenec',
     u'Invalidi_St_mest': 9,
     u'KoordinataX': 466947,
     u'KoordinataX_wgs': 14.567929171694901,
     u'KoordinataY': 101247,
     u'KoordinataY_wgs': 46.05457609543313,
     u'Opis': u'2,40 \u20ac /dan',
     u'St_mest': 187,
     u'Tip_parkirisca': None,
     u'U_delovnik': u'24 ur (ponedeljek - petek)',
     u'U_sobota': None,
     u'U_splosno': None,
     u'Upravljalec': u'JP LPT d.o.o.'}
    Traceback (most recent call last):
      File "test.py", line 14, in <module>
        zas = carpark['zasedenost']
    KeyError: 'zasedenost'
    

    如您所见,错误非常准确。字典中没有键'zasedenost'。如果您查看JSON,您会发现该数组中的许多元素都是正确的。

    我建议修复,但在没有此词典键的情况下,我不知道你想要做什么。也许你想要这样的东西:

    zas = carpark.get('zasedenost')
    if zas is not None:
        free_spaces = zas.get('P_kratkotrajniki')
        last_updated = zas.get('Cas_timestamp')
    else:
        free_spaces = None
        last_updated = None