检查json输出中的键是否存在

2024-09-28 19:21:41 发布

您现在位置:Python中文网/ 问答频道 /正文

在尝试解析某些json时,我一直收到以下错误:

Traceback (most recent call last):
  File "/Users/batch/projects/kl-api/api/helpers.py", line 37, in collect_youtube_data
    keywords = channel_info_response_data['items'][0]['brandingSettings']['channel']['keywords']
KeyError: 'brandingSettings'

如何确保在将键分配给变量之前检查JSON输出?如果找不到键,那么我只想指定一个默认值。代码如下:

^{pr2}$

Tags: apijsonmostdata错误batchchannelcall
3条回答

假设您有一个dict,您有两个选项来处理key not exist情况:

1)获取具有默认值的密钥,例如

d = {}
val = d.get('k', 10)

val将为10,因为没有名为k的密钥

2)尝试例外

^{pr2}$

这种方法更灵活,因为您可以在except块中执行任何操作,甚至可以忽略pass语句的错误,如果您真的不在乎它的话。在

你可以把你的作业打包成

try:
    keywords = channel_info_response_data['items'][0]['brandingSettings']['channel']['keywords']
except KeyError as ignore:
    keywords = "default value"

或者,假设使用.has_key(...)。依我看,在你的情况下,第一个解决方案是最好的

How do I make sure that I check my JSON output

此时,“JSON输出”只是一个普通的原生Python dict

for a key before assigning it to a variable? If a key isn’t found, then I just want to assign a default value

现在您知道您有一个dict,浏览dict方法的官方文档应该可以回答以下问题:

https://docs.python.org/3/library/stdtypes.html#dict.get

get(key[, default])

Return the value for key if key is in the dictionary, else default. If default is not given, it defaults to None, so that this method never raises a KeyError.

所以一般情况是:

var = data.get(key, default)

现在,如果您有深度嵌套的dict/list,其中可能缺少任何键或索引,那么捕捉KeyErrors和indexerErrors会更简单:

^{pr2}$

另请注意:代码片段中充满了重复的channel_info_response_data['items'][0]['statistics']channel_info_response_data['items'][0]['snippet']表达式。使用中间变量将使代码更易读、更易于维护,并且速度更快:

# always set a timeout if you don't want the program to hang forever
channel_info_response = requests.get(channel_info_url, timeout=30)
# always check the response status - having a response doesn't
# mean you got what you expected. Here we use the `raise_for_status()`
# shortcut which will raise an exception if we have anything else than
# a 200 OK.
channel_info_response.raise_for_status()

# requests knows how to deal with json:
channel_info_response_data = channel_info_response.json()

# we assume that the response MUST have `['items'][0]`,
# and that this item MUST have "statistics" and "snippets"
item = channel_info_response_data['items'][0]
stats = item["statistics"] 
snippet = item["snippet"]

no_of_videos = int(stats.get('videoCount', 0))
no_of_subscribers = int(stats.get('subscriberCount', 0))
no_of_views = int(stats.get('viewCount', 0))
avg_views = round(no_of_views / no_of_videos, 0)

try:
   photo = snippet['thumbnails']['high']['url']
except KeyError:
   photo = None

description = snippet.get('description', "")
start_date = snippet.get('publishedAt', None)
title = snippet.get('title', "")
try:
   keywords = item['brandingSettings']['channel']['keywords']
except KeyError
   keywords = ""

您可能还想了解字符串格式(连续的字符串很容易出错,几乎不可读),以及how to pass arguments to ^{}

相关问题 更多 >