字典中存在键时引发KeyError

时间:2020-07-23 21:33:16

标签: python json

我有一段代码应该喷射一个json输入,并使用for循环将数据放入我放置在databae中的行中。 当我尝试从字典中获取值时,会给我一个错误,但是,如果我尝试不使用循环就访问该值,它会起作用。

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()

输出消息:

2359453249886770269_10139873678
2359453249886770269_10139873678
2359453249886770269_10139873678

错误消息:

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

2 个答案:

答案 0 :(得分:1)

您确定每个 media都有一个ID吗?看来您只是在打印id,直到它们不再存在为止。您应该处理该错误并打印结果,以便查看包含在哪种介质中并得出解决方案。

#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 :当您收到KeyError(或同等学历)时,您应该始终要做的第一件事就是打印密钥所在的整个内容。所用的语言,数据的来源或其他任何都无关紧要。可以反复使用上述解决方案(或等效解决方案),唯一的实际变化是:如果您不在循环中,请摆脱中断/继续的内容。您可能是StackOverflow上第10百万个问“我的数据有什么问题?”的人,但从来没有打扰打印自己的数据以查看。

想象一下,如果您不问这个问题并复制/粘贴您的所有代码,而只是在分配print(media)之前写了x(strong和肮脏的方式,暂时)。不要个人化。 25年前,我犯了同样的错误,但是没有人要问,并且一直犯这个错误,直到它出现在我眼前,才打印出该死的东西:之前:D。最终,我学会了像上面的代码一样处理该问题。给你代码是一条鱼。给您这个小窍门教您如何钓鱼。

答案 1 :(得分:1)

sectional_item['layout_content']['two_by_two_item']['channel']['media']持有的值是带有一些未知键的字典。 “ id”不是这些键之一。

尝试在您的错误点之前执行此操作

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