使用Python从API提取特定JSON数据(Discord.py机器人问题)
问题
我正在制作一个小型Discord.py机器人作为Python/API实验项目,目标是在Discord中按需打印API返回的特定数据。相关代码如下:
@client.command() async def otherusers(ctx, player): rs = requests.get(apiLink + "/checkban?name=" + str(player)) if rs.status_code == 200: rs = rs.json() embed = discord.Embed(title="Other users for" + str(player), description="""User is known as: """ + str(rs["usedNames"])) await ctx.send(embed=embed)
API返回示例如下:
{"id":1536171865,"avatar":"https://secure.download.dm.origin.com/production/avatar/prod/userAvatar/41472001/208x208.PNG","name":"_7cV","vban":{"A1 Army of One":{"bannedUntil":null,"reason":"ping >1000"}},"ingame":[],"otherNames":{"updateTimestamp":"2022-07-08T10:10:50.939000","usedNames":["ABCDE123","ABCDE1234","ABCDE12345","ABCDE1234567"]}}
当我将代码中的字符串改为str(rs["otherNames"])时可正常运行,但我只想提取用户名列表。若改为str(rs["usedNames"]),在Discord中调用命令时PyCharm会抛出错误:discord.ext.commands.errors.CommandInvokeError: Command raised an exception: KeyError: 'usedNames'
恳请帮忙解决此问题。
解决方案
核心原因
usedNames不是API返回JSON的顶级键,它嵌套在otherNames这个子对象里,直接访问rs["usedNames"]自然找不到对应的键,触发KeyError。
基础修正代码
调整键的访问路径,从rs["usedNames"]改为rs["otherNames"]["usedNames"]就能正确获取用户名列表:
@client.command() async def otherusers(ctx, player): rs = requests.get(apiLink + "/checkban?name=" + str(player)) if rs.status_code == 200: rs = rs.json() # 正确访问嵌套的usedNames列表 used_names = rs["otherNames"]["usedNames"] # 将列表转为更易读的分行格式 names_display = "\n".join(used_names) embed = discord.Embed(title=f"Other users for {player}", description=f"User is known as:\n{names_display}") await ctx.send(embed=embed)
进阶容错处理
为避免API返回结构变化(比如缺失otherNames或usedNames字段)导致命令崩溃,建议用dict.get()做容错处理:
@client.command() async def otherusers(ctx, player): rs = requests.get(apiLink + "/checkban?name=" + str(player)) if rs.status_code == 200: rs = rs.json() # 逐层获取字段,缺失时返回默认值 other_names_data = rs.get("otherNames", {}) used_names = other_names_data.get("usedNames", ["No alternative names found"]) names_display = "\n".join(used_names) embed = discord.Embed(title=f"Other users for {player}", description=f"User is known as:\n{names_display}") await ctx.send(embed=embed) else: await ctx.send(f"Failed to fetch data. Status code: {rs.status_code}")
内容的提问来源于stack exchange,提问作者nOsfezodus
相关产品推荐
相关产品推荐

