【问题标题】:How to avoid omissions in video information acquisition when using the YouTube Data API?使用 YouTube Data API 时如何避免视频信息获取的遗漏?
【发布时间】:2021-04-29 20:23:57
【问题描述】:

假设/我想要实现的目标

我想用YouTube Data API V3获取视频ID,不遗漏,看看是代码还是YouTube的视频设置(API端)出了问题。

问题

以下代码用于从 YouTube Data API 获取视频信息,但我得到的 ID 数量与实际发布的视频数量不匹配。

from apiclient.discovery 
import build
id = "UCD-miitqNY3nyukJ4Fnf4_A" #sampleID

token_check = None
nextPageToken = None
id_info = []

while True:
    if token_check != None:
        nextPageToken = token_check

    Search_Video = youtube.search().list(
        part = "id",
        channelId = id,
        maxResults = 50,
        order = 'date',
        safeSearch = "none",
        pageToken = nextPageToken
    ).execute()

    for ID_check in Search_Video.get("items", []):
        if ID_check["id"]["kind"] == "youtube#video":
            id_info.append(ID_check["id"]["videoId"])

    try:
        token_check = Search_Video["nextPageToken"]
    except:
        print(len(id_info)) #check number of IDs
        break

我也使用了YouTube Data API函数来获取频道的videoCount信息,注意到videoCount的值与上面代码获取的ID数量不匹配,所以我发布了这个.

根据channels() API,这个频道有 440 个视频,但上面的代码只有 412 个视频(在 JST 上午 10:30)。

补充信息

・Python 3.9.0

・YouTube 数据 API v3

【问题讨论】:

    标签: youtube youtube-api youtube-data-api


    【解决方案1】:

    您必须承认Search.list API 端点没有清晰的行为。这意味着您不应该期望从中获得精确的结果。 Google 并没有记录这种行为,但是这个论坛有很多来自经历过这种行为的用户的帖子。

    如果要获取给定频道上传的所有视频的ID,则应采用以下两步过程:

    第一步:获取频道的Uploads播放列表ID。

    调用Channels.list API 端点,将其请求参数id 设置为您感兴趣的频道的ID(或者,将其请求参数mine 设置为true)进行查询以获取该频道的上传播放列表 ID,contentDetails.relatedPlaylists.uploads

    def get_channel_uploads_playlist_id(youtube, channel_id):
        response = youtube.channels().list(
            fields = 'items/contentDetails/relatedPlaylists/uploads',
            part = 'contentDetails',
            id = channel_id,
            maxResults = 1
        ).execute()
    
        items = response.get('items')
        if items:
            return items[0] \
                ['contentDetails'] \
                ['relatedPlaylists'] \
                .get('uploads')
        else:
            return None
    

    请注意,函数get_channel_uploads_playlist_id 只能调用一次以获取上传的播放列表 给定频道的 ID;随后根据需要多次使用该 ID。

    第 2 步:检索播放列表的所有视频 ID。

    调用PlaylistItems.list API端点,查询其请求参数playlistId设置为从get_channel_uploads_playlist_id获取的ID:

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

    请注意,当使用Google's APIs Client Library for Python(和你一样)时,API result set pagination 非常简单:只需使用对应于相应分页 API 端点的 Python API 对象的 list_next 方法(如上所示) ):

    request = API_OBJECT.list(...)
    
    while request:
        response = request.execute()
        ...
        request = API_OBJECT.list_next(
            request, response)
    

    还要注意,上面我使用了两次fields 请求参数。这是一个很好的做法:只向 API 询问实际使用的信息。

    还有一个重要提示:PlaylistItems.list 端点在使用 API 密钥调用时不会返回与频道的私有视频对应的项目。当您的 youtube 对象是通过调用函数 apiclient.discovery.build 并将参数 developerKey 传递给它来构造时,就会发生这种情况。

    PlaylistItems.list 仅将与私人视频对应的项目返回给频道所有者。当youtube 对象是通过调用函数apiclient.discovery.build 来构造时会发生这种情况,将参数credentials 传递给它,如果credentials 引用拥有相应播放列表的频道。

    另外一个重要说明:根据Google staff,当查询给定频道的上传播放列表时,通过PlaylistItems.list 端点返回的项目数设计设置了上限20000。这很不幸,但却是事实。

    【讨论】:

      猜你喜欢
      • 2012-12-14
      • 2015-03-15
      • 1970-01-01
      • 2015-08-10
      • 2021-01-23
      • 1970-01-01
      • 2013-05-09
      • 2013-04-04
      • 2013-03-03
      相关资源
      最近更新 更多