首页 > 解决方案 > Discordbot TypeError:只能将str(不是“NoneType”)连接到str

问题描述

我是 python 新手并尝试制作一个不和谐的机器人,TypeError: can only concatenate str (not "NoneType") to str当机器人发送消息显示“歌曲名称”按名称而不是 url 搜索并且不知道如何修复它时,我得到了这个,当我使用 url 时它工作正常

@client.command(pass_context = True)
async def play(ctx, *, url):
  if (ctx.author.voice):
    channel = ctx.message.author.voice.channel
    voice = get(client.voice_clients, guild=ctx.guild)
    if voice and voice.is_connected():
      await voice.move_to(channel)
    else:
      voice = await channel.connect()
  else:
    await ctx.send('`You are not in a voice channel`')

  YDL_OPTIONS = {'format': 'bestaudio', 'noplaylist': 'True', 'default_search':"ytsearch"}
  FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', 'options': '-vn'}
  voice = get(client.voice_clients, guild=ctx.guild)
  with YoutubeDL(YDL_OPTIONS) as ydl:
      info = ydl.extract_info(url, download=False)
      if 'entries' in info:
        url = info["entries"][0]["formats"][0]['url']
      elif 'formats' in info:
          url = info["formats"][0]['url']
  if not voice.is_playing():
      voice.play(FFmpegPCMAudio(url, **FFMPEG_OPTIONS), after=lambda x=0: check_queue(ctx, ctx.message.guild.id))

      embed_p = discord.Embed(colour = discord.Colour.magenta())
      embed_p.add_field(name='Playing:『  ' + info.get('title')+' 』', value='『'+ctx.author.mention+'』' , inline=False)
      await ctx.send(embed=embed_p)

标签: pythondiscord.py

解决方案


当您想要使用其中的数据时,您需要了解您将来尝试访问的数据结构。您记录的 info 变量如下所示:


   "_type":"playlist",
   "entries":[
      {
         "id":"dQw4w9WgXcQ",
         "title":"Rick Astley - Never Gonna Give You Up (Official Music Video)",
         "formats":[
            {
               "asr":48000,
               "filesize":1232413,
               "format_id":"249",
               .....

并且持续很长时间。

现在,如果您尝试从 中访问 title info,您将得到 None 因为 title 不存在于info. 但是,如果您深入到该对象中,您会发现有一个

"title":"Rick Astley - Never Gonna Give You Up (Official Music Video)"

要访问它,您首先要访问info,然后entries,这是一个数组,可以在我上面提供的格式片段中看到。然后您可以访问条目中包含标题的第一个对象。

替换info.get('title')info['entries'][0]['title']


推荐阅读