Dan A
Dan A

Reputation: 414

Searching Channels with YouTube API returns incorrect results

Using this code allows me to search for YouTube channels and return their statistics; for some reason, however, only about half the channels return any results.

For example, if I use this link to test the API, you can see that I searched for Animal Planet, and that yields no results. However, if we go to YouTube's website and search for the same thing, we get the channel as needed.

Why does this happen and how can this be fixed?

This is the code I used:

    @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}")

Upvotes: 1

Views: 480

Answers (1)

stvar
stvar

Reputation: 6965

You have to acknowledge that invoking the Channels.list API endpoint, by passing to it the parameter forUsername, is by no means the same thing as going to the YouTube's Web UI for to apply a manual search. For these things to come to light, do bear with me for a little while...

According to the official docs, the Channels.list endpoint invoked with forUsername=... produces the meta-data associated to the channel of which username is given as argument to the parameter forUsername:

forUsername (string)

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

According to an official Google staff post from 2013-07-11, it's not a requisite that every channel have attached an username. Hence, is perfectly possible for Channels.list endpoint to return no channel at all, if the argument of forUsername does not represent a YouTube username.

If you use one of my public (MIT licensed) Python 3 script -- youtube-search.py --, you'll see that it returns nothing for your queried username Animal Planet:

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

But if you invoke that script as follows:

$ 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

you'll see pretty much the same output as the YouTube's Web UI will show when queried for the same search term and filtered for TYPE being Channel.

YouTube Web UI Screenshot

Do note that your own results (the one obtained from youtube-search.py and the other provided by the YouTube Web UI) may very likely differ from the above ones; this is so because Google searches are tailored for the user that initiates the query.

The explanation behind the matching results sets obtained from youtube-search.py and YouTube Web UI is the following:

The API endpoint that corresponds to YouTube's own search feature accessible via its Web UI is none other than Search.list.

Do convince yourself about this claim by reading the code of youtube-search.py: when invoking it with --search-term "Animal Planet" --type channel, that script executes the function 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()
       ...

with term equal to the string Animal Planet and type equal to the string channel. Consequently, this script is calling for the Search.list endpoint, passing to it the parameters q and type as mentioned.

Upvotes: 2

Related Questions