TransWikia.com

KeyError is raised when key exists in dictionary

Stack Overflow Asked by Andrey Kiselev on December 18, 2021

I have a piece of code that should jet a json input and with for loops seperate the data in rows that I place in a databae.
When I try to get a value from a dictionary it gives me an error, however if I try to acces the value without using the loops it works.

from api import DataBase2
import json

db = DataBase2.DataBase2('../database/db1.json')
json_file = json.load(open('yes.txt', 'r', encoding='utf-8'))
#sectional_items[0].layout_content.two_by_two_item.channel.media.media_type
for sectional_item in json_file['sectional_items']:
    medias = []
    if 'two_by_two_item' in sectional_item['layout_content']:
        medias.append(sectional_item['layout_content']['two_by_two_item']['channel']['media'])
    for fill_media in sectional_item['layout_content']['fill_items']:
        medias.append(fill_media)
    for media in medias:
        x = media['id']
        print(x)
        print(type(x))
        x = media.get('id')
        print(x)
        print(type(x))
        if media['media_type'] != 1:
            continue
        best_photo = ''
        best_photo_height = 0
        best_photo_width = 0
        for candidate in media['image_versions2']['candidates']:
            if candidate['height'] > best_photo_height or candidate['width'] > best_photo_width:
                best_photo_height = candidate['height']
                best_photo_width = candidate['width']
                best_photo = candidate['url']
                base = [media['id'], media['device_timestamp'], media['media_type'], media['code'], best_photo,
                        media['image_versions2']['candidates'][2], media['user']['username'], media['comment_count'],
                        media['like_count'],
                        media['caption']['text']]
                db.create_row('got_from_ig', 'media', base)
db.show_table('got_from_ig', 'media')
db.save()

Output message:

2359453249886770269_10139873678
2359453249886770269_10139873678
2359453249886770269_10139873678

Error message:

Traceback (most recent call last):
  File "C:/Users/user/PycharmProjects/scraper/api/yes.py", line 14, in <module>
    x = media['id']
KeyError: 'id'

2 Answers

The value held by sectional_item['layout_content']['two_by_two_item']['channel']['media'] is a dictionary with some unknown keys. 'id' is not one of those keys.

try doing this just before your error point

for key in media.keys():
    print(key)
    print(media[key])

Answered by Pulsar on December 18, 2021

Are you sure that every media has an id? It would seem you are only printing id's until they don't exist anymore. You should handle the error and print the results so you can see what media contains and derive a solution.

#temporary func for debugging purposes
def debug_print(baddata, msg='bad data'):
    #this line just makes it easier to read
    itemized = 'n'.join([f't{k}:{v}' for k, v in baddata.items()])
    print(f'Problem: {msg}n{itemized}')
    return input('(c)ontinue else break? ')


for media in medias:
    try:
        #replace this comment with your loop code and catch all/any key errors
    except KeyError as err:
        if debug_print(media, str(err)) == 'c':
            continue
        else:
            break

ProTip: When you receive a KeyError(or equivalent) the first thing you should always do is print the entire thing that the key was in. It doesn't matter what language you are using, where the data came from or anything else. The above solution (or equivalent) can be used over and over with the only real change being: if you aren't in a loop, get rid of the break/continue stuff. You may be the 10 millionth person on StackOverflow to ask "What is wrong with my data?", but never bothered to print your own data to see.

Imagine how much time you would have saved if instead of asking this question and copy/pasting all your code, you simply wrote print(media) before assigning x (the quick and dirty way of doing it, temporarily). Don't take it personal. 25 years ago I was making the same mistakes, but didn't have anyone to ask, and kept making the mistake til it dawned on me to just print the damn thing before the problem :D. Eventually I learned to handle the problem like the code above does. Giving you code is a fish. Giving you this tip teaches you how to fish.

Answered by Michael Guidry on December 18, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP