使用discord.py开发音乐Discord机器人时yt-search库出现badRequest错误的解决求助
解决yt-search抛出的SearchError: badRequest问题(Discord音乐机器人)
我刚看了你的代码和问题描述,这个badRequest错误大概率是YouTube Data API密钥的问题,再加上你对yt-search的使用逻辑有点小问题,咱们一步步来解决:
1. 先搞定核心问题:有效的YouTube Data API密钥
yt-search底层依赖YouTube Data API来做搜索,你代码里写的yt_search.build("API Key")只是个占位符,必须换成真实有效的密钥:
- 去Google Cloud控制台创建一个新项目,然后启用YouTube Data API v3
- 生成一个API密钥,注意别给密钥加不必要的IP限制(如果你的机器人在云服务器上,得确保服务器IP在允许列表里),也不要限制API的使用范围(至少要允许YouTube Data API)
- 把代码里的
"API Key"替换成你刚拿到的真实密钥字符串
2. 修正yt-search的使用逻辑
你现在的代码里对搜索结果的处理是错的:yt.search()返回的是搜索结果列表,不是单个对象,直接调用search_result.title肯定会报错。而且你的错误捕获范围太广,应该只在输入不是YouTube链接的时候才触发搜索,而不是捕获所有下载错误。
3. 调整后的代码片段(play命令部分)
我帮你修正了play命令的关键逻辑,你可以直接替换原来的代码:
@client.command() async def play(ctx, *, query: str = None): # 改成*query支持带空格的标题搜索 if query is None: await ctx.send("请输入YouTube视频链接或标题,格式:?play [链接/标题]") return song_there = os.path.isfile("song.mp3") try: if song_there: os.remove("song.mp3") except PermissionError: await ctx.send("请等待当前播放的音乐结束,或者使用?stop命令停止播放") return # 语音频道连接逻辑保持不变 channel = discord.utils.get(ctx.guild.voice_channels, name="music lounge") voice = discord.utils.get(client.voice_clients, guild=ctx.guild) if voice is None or not voice.is_connected(): voice = await channel.connect() ydl_opts = { 'format': "bestaudio", 'postprocessors': [{ 'key': "FFmpegExtractAudio", 'preferredcodec': "mp3", 'preferredquality': "192" }] } # 先判断是不是YouTube链接,不是的话再搜索 is_youtube_link = "youtube.com" in query or "youtu.be" in query target_url = query if not is_youtube_link: try: # 初始化yt-search,用真实API密钥 yt = yt_search.build("你的真实API密钥") # 搜索视频,取第一个结果 search_results = yt.search(query, sMax=1, sType=["video"]) if not search_results: await ctx.send("没有找到匹配的视频哦") return # 拿到第一个结果的视频ID,拼接成YouTube链接 target_url = f"https://www.youtube.com/watch?v={search_results[0].videoId}" await ctx.send(f"找到匹配视频:{search_results[0].title},开始下载...") except yt_search.errors.SearchError as e: await ctx.send(f"搜索出错了:{str(e)}") return else: await ctx.send("开始下载音乐...") # 下载音频 try: with youtube_dl.YoutubeDL(ydl_opts) as ydl: ydl.download([target_url]) except Exception as e: await ctx.send(f"下载失败:{str(e)}") return # 重命名文件并播放 for file in os.listdir("./"): if file.endswith(".mp3"): os.rename(file, "song.mp3") voice.play(discord.FFmpegPCMAudio("song.mp3"))
额外注意事项
- 别忘了检查你的API密钥配额:YouTube Data API有每日请求配额限制,超过了也会报类似的错误,你可以在Google Cloud控制台查看配额使用情况
- 不要把API密钥和Bot Token硬编码在代码里,最好用环境变量来管理,比如
os.getenv("YOUTUBE_API_KEY") - 确保你的机器人运行环境能正常访问Google的API,比如如果是国内服务器,可能需要配置代理
内容的提问来源于stack exchange,提问作者user15790573
相关产品推荐
相关产品推荐

