简体   繁体   English

字典中存在键时引发 KeyError

[英]KeyError is raised when key exists in dictionary

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.我有一段代码应该喷射一个 json 输入,并使用 for 循环将我放置在数据库中的行中的数据分开。 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: Output 消息:

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'

Are you sure that every media has an id?你确定每个media都有一个id吗? It would seem you are only printing id's until they don't exist anymore.看起来你只是在打印 id 直到它们不再存在。 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.专业提示:当您收到KeyError (或等效项KeyError时,您应该始终做的第一件事是打印密钥所在的整个内容。您使用什么语言、数据来自哪里或其他任何内容都没有关系。 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.您可能是 StackOverflow 上第 1000 万人问“我的数据有什么问题?”,但从不费心打印自己的数据来查看。

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).想象一下,如果您不问这个问题并复制/粘贴所有代码,而是在分配x之前简单地编写print(media) (临时的快速而肮脏的方式),那么您将节省多少时间。 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. 25 年前,我犯了同样的错误,但没有人可以问,并且一直在犯错误,直到我意识到在问题之前打印该死的东西: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.给你这个技巧教你如何钓鱼。

The value held by sectional_item['layout_content']['two_by_two_item']['channel']['media'] is a dictionary with some unknown keys. sectional_item['layout_content']['two_by_two_item']['channel']['media']持有的值是一个带有一些未知键的字典。 'id' is not one of those keys. 'id' 不是这些键之一。

try doing this just before your error point尝试在您的错误点之前执行此操作

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM