使用 YouTube 搜索频道 API returns 个不正确的结果

Searching Channels with YouTube API returns incorrect results

使用此代码可以搜索 YouTube 频道和 return 他们的统计信息;然而,出于某种原因,只有大约一半的频道 return 有任何结果。

例如,如果我使用此 link to test the API,您可以看到我搜索了 Animal Planet,但没有得到任何结果。但是,如果我们去 YouTube 的网站并搜索相同的东西,我们会根据需要获得频道。

为什么会发生这种情况,如何解决?

这是我使用的代码:

    @commands.command()
    async def yt_test(self, ctx, *, search):
        api_key = '...'
        youtube = build('youtube', 'v3', developerKey=api_key)
        request = youtube.channels().list(
            part="snippet,statistics",
            forUsername=search,
            maxResults=1
        )
        response = request.execute()
        try:
            for item in response['items']:
                link = item['id']
                thumb_image = item['snippet']['thumbnails']['default']['url']
                views = "{:,}".format(int(item['statistics']['viewCount']))
                subs = "{:,}".format(int(item['statistics']['subscriberCount']))
                vidCount = "{:,}".format(int(item['statistics']['videoCount']))
        except:
            Notfound = discord.Embed(description= "Sorry, but this Channel was not located, check spelling" , color=0xfc0328)
            await ctx.send(embed=Notfound)
    
        finalresult = discord.Embed(title = search, url='https://www.youtube.com/channel/' + link, 
        description= '**Statistics**\nViews: ' + views + '\nSubscribers: ' + subs + "\nVideos: " + vidCount, color=0x00ff00)
        finalresult.set_thumbnail(url = thumb_image)
        await ctx.send(embed=finalresult)
        print(f"{ctx.author} looked up the profile of {search} --- in #{ctx.guild.name}")

您必须承认,调用 Channels.list API endpoint, by passing to it the parameter forUsername 与访问 YouTube 网站 UI 进行手动搜索绝不是一回事。为了让这些事情曝光,请耐心等待我一会儿...

根据官方文档,使用 forUsername=... 调用的 Channels.list 端点会生成与通道相关联的 meta-data,该通道的用户名作为参数 forUsername:

forUsername (string)

The forUsername parameter specifies a YouTube username, thereby requesting the channel associated with that username.

根据 2013 年 7 月 11 日的 an official Google staff post并非每个频道都必须附加用户名。因此,如果 forUsername 的参数不代表 YouTube 用户名,Channels.list 端点完全有可能完全没有频道 return。

如果您使用我的 public(MIT 许可)Python 3 脚本之一 -- youtube-search.py --,您会发现它 return 什么都没有对于您查询的用户名 Animal Planet:

$ python3 youtube-search.py --user-name "Animal Planet"
youtube-search.py: error: user name "Animal Planet": no associated channel found

但是如果您按如下方式调用该脚本:

$ python3 youtube-search.py --search-term "Animal Planet" --type channel
UCkEBDbzLyH-LbB2FgMoSMaQ: Animal Planet
UCuTSm59-_kap6J7Se-orUVA: Animal Planet Latinoamérica
UCpvajaPSWvFlyl83xvzs65A: animalplanet românia
UCgyOEJZJLPKclqrDyUkZ6Ag: Animal planet 1
UCypzlOdJyyOR2NhKv0o3zig: 動物星球頻道/ Animal Planet Taiwan
UCmMm-p51c14XJ1p294faCmA: Animal Planet Brasil
UCejVe2sNPjjvfCXg35q_EQQ: Animal Planet Videos
UClQLf_zw2A_nRaB45HWTbtA: Your Animal Planet
UChQEdt9dBiCkcCch6LyrjtA: Cute Animal Planet
UCRIS8Y1kfrFvFF_6vt6_3Cg: Animal Planet Videos

你会看到与 YouTube 的 Web UI 几乎相同的输出,当查询相同的搜索词并过滤 TYPE 时显示 Channel

请注意,您自己的结果(从 youtube-search.py 获得的结果和 YouTube 网站 UI 提供的另一个结果)很可能与上述结果不同;这是因为 Google 搜索是为发起查询的用户量身定制的。

youtube-search.py 和 YouTube Web UI 获得的匹配结果集背后的解释如下:

与可通过其 Web UI 访问的 YouTube 自己的搜索功能相对应的 API 端点是 none 而不是 Search.list.

通过阅读 youtube-search.py 的代码让自己相信这个说法:当用 --search-term "Animal Planet" --type channel 调用它时,该脚本执行函数 Service.search_term:

class Service:
    ...
    def search_term(self, term, type = None):
        resp = self.youtube.search().list(
            q = term,
            type = type,
            part = 'id,snippet',
            fields = 'items(id,snippet(title))',
            maxResults = self.max_results
        ).execute()
       ...

其中 term 等于字符串 Animal Planettype 等于字符串 channel。因此,此脚本正在调用 Search.list 端点,将参数 q and type 传递给它。