Discord Bot调用Tenor API生成GIF时出现KeyError: 'media'错误求助
问题描述
我正在Visual Studio Code中开发Discord机器人作为课外项目,想要添加生成GIF的命令,通过Tenor API实现。参考相关教程和Stack Overflow问题后编写了代码,但在服务器执行!gif命令时出现错误:
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: KeyError: 'media'
我的代码如下:
import requests import discord from discord.ext import commands TenorToken=str('TenorToken') DiscordToken=str('DiscordToken') @bot.event async def on_ready(): print('Logged in as '+ bot.user.name +'!') def get_gif(searchTerm): r=requests.get("https://tenor.googleapis.com/v2/search?q=%s&key=%s&client_key=%s&limit=%s"%(searchTerm, TenorToken,DiscordToken,1)) data=r.json() for result in data['results']: print('- result -') #print(result) for media in result['media']: print('- media -') #print(media) #print(media['gif']) print('url:', media['gif']['url']) return data['results'][0]['media'][0]['gif']['url'] @bot.command(name='gif') async def on_message(ctx,arg): gif_url=get_gif(arg) embed=discord.Embed() embed.set_image(url=gif_url) await ctx.send(embed=embed) bot.run(DiscordToken)
解决方案
核心问题分析
- Tenor V2 API结构变更:你写的代码用了旧版API的
media字段,但Tenor V2 API的GIF资源实际在media_formats下,这是触发KeyError: 'media'的直接原因。 - API参数错误:
client_key应该是自定义的应用标识(比如discord_gif_bot),而非Discord机器人Token,错误的参数可能导致API返回异常响应。 - 缺少错误防护:没有检查请求是否成功、搜索结果是否为空,直接索引字典会在异常情况触发KeyError。
- Bot实例未初始化:代码里没有创建
bot实例,装饰器无法正常绑定到Bot对象。
修正后的完整代码
import requests import discord from discord.ext import commands # 替换为你的真实密钥 TENOR_API_KEY = "你的TenorToken" DISCORD_BOT_TOKEN = "你的DiscordToken" # 初始化Bot,指定命令前缀和必要权限 bot = commands.Bot(command_prefix="!", intents=discord.Intents.default()) @bot.event async def on_ready(): print(f'Logged in as {bot.user.name}!') def get_gif(search_term): # 修正API请求参数,client_key用自定义标识 request_url = f"https://tenor.googleapis.com/v2/search?q={search_term}&key={TENOR_API_KEY}&client_key=discord_gif_bot&limit=1" response = requests.get(request_url) # 检查请求是否成功 if response.status_code != 200: print(f"Tenor API请求失败,状态码: {response.status_code}") return None data = response.json() # 检查搜索结果是否存在且不为空 if "results" not in data or len(data["results"]) == 0: print("未找到匹配的GIF") return None # 安全解析GIF URL,捕获可能的KeyError try: return data["results"][0]["media_formats"]["gif"]["url"] except KeyError as e: print(f"解析API响应出错: {e}") return None @bot.command(name='gif') async def gif_command(ctx, *, search_term): # 用*接收多关键词搜索(比如!gif cat playing) gif_url = get_gif(search_term) if not gif_url: await ctx.send("找不到对应的GIF哦!") return embed = discord.Embed() embed.set_image(url=gif_url) await ctx.send(embed=embed) bot.run(DISCORD_BOT_TOKEN)
关键修改说明
- 新增Bot实例初始化代码,确保装饰器能正常工作
- 适配Tenor V2 API的
media_formats字段获取GIF URL - 为API请求添加状态码检查、结果非空检查,用try-except处理解析异常
- 修改命令参数为
*, search_term,支持多关键词搜索 - 替换错误的
client_key参数值,符合Tenor API要求
内容的提问来源于stack exchange,提问作者Cameron Fabela
相关产品推荐
相关产品推荐

