youtube-data-apigoogle-data-api

YouTube Data API V3 - Maximum search result for Channel ID


I came across the API reference document regarding the Search API:

Note: Search results are constrained to a maximum of 500 videos if your request specifies a value for the channelId parameter and sets the type parameter value to video, [...].

Do I have to apply for paid account to break the 500 videos limit? If yes, how do I apply?


Solution

  • If you need to obtain the list of all videos of a given channel -- identified by its ID, say CHANNEL_ID --, then you have to proceed as follows:

    Step 1: Query the Channels.list API endpoint with parameter id=CHANNEL_ID for to obtain from the API the ID of that channel's uploads playlist:

    response = youtube.channels().list(
        id = CHANNEL_ID,
        part = 'contentDetails',
        fields = 'items(contentDetails(relatedPlaylists(uploads)))',
        maxResults = 1
    ).execute()
    
    uploads_id = response \
        ['contentDetails'] \
        ['relatedPlaylists'] \
        ['uploads']
    

    The code above should run only once for obtaining the uploads playlist ID as uploads_id, then that ID should be used as many times as needed.

    Usually, a channel ID and its corresponding uploads playlist ID are related by s/^UC([0-9a-zA-Z_-]{22})$/UU\1/.

    Step 2: Using the previously obtained uploads playlist ID -- let's name it UPLOADS_ID --, query the PlaylistItems.list API endpoint for to obtain the list of all video ID's of that playlist:

    is_video = lambda item: \
        item['snippet']['resourceId']['kind'] == 'youtube#video'
    video_id = lambda item: \
        item['snippet']['resourceId']['videoId']
    
    request = youtube.playlistItems().list(
        playlistId = UPLOADS_ID,
        part = 'snippet',
        fields = 'nextPageToken,items(snippet(resourceId))',
        maxResults = 50
    )
    videos = []
    
    while request:
        response = request.execute()
    
        items = response.get('items', [])
    
        videos.extend(map(video_id, filter(is_video, items)))
    
        request = youtube.playlistItems().list_next(
            request, response)
    

    Upon running the code above, the list videos will contain the IDs of all videos that were uploaded on the channel identified by CHANNEL_ID.

    Step 3: Query the Videos.list API endpoint for to obtain the statistics info (i.e. object) of each of the videos you're interested in:

    class Stat:
    
        def __init__(video_id, view_count, like_count):
            self.video_id = video_id
            self.view_count = view_count
            self.like_count = like_count
    
    stats = []
    
    while len(videos):
        ids = videos[0:50]
        del videos[0:50]
    
        response = youtube.videos().list(
            id = ','.join(ids),
            part = 'id,statistics',
            fields = 'items(id,statistics)',
            maxResults = len(ids)
        ).execute()
    
        items = response['items']
        assert len(items) == len(ids)
    
        for item in items:
            stat = item['statistics']
            stats.append(
                Stat(
                    video_id = item['id'],
                    view_count = stat['viewCount'],
                    like_count = stat['likeCount']
                )
            )
    

    Note that code above, in case the list videos has length N, reduces the number of calls to Videos.list from N to math.floor(N / 50) + (1 if N % 50 else 0). That's because the parameter id of Videos.list endpoint can be specified as a comma-separated list of video IDs (the number of IDs in one such list can be maximum 50).

    Note also that each piece of code above uses the fields request parameter for to obtain from the invoked API endpoints only the info that is of actual use.


    I must also mention that according to YouTube's staff, there's an upper 20000 limit set by design for the number of items returned via PlaylistItems.list endpoint. This is unfortunate, but a fact.