首页 > 解决方案 > YouTube 数据 API:从 Search.list 结果集中排除直播

问题描述

今天我有一个(我认为)简单的问题。Search.list我想从我的 YouTube 数据 API结果集中排除 YouTube 直播。我怎样才能做到这一点?我在 API 的文档中找不到执行此操作的函数。

这就是我尝试过的:

https://www.googleapis.com/youtube/v3/search?channelId=UCZMsvbAhhRblVGXmEXW8TSA&part=snippet,id&order=viewCount&maxResults=1&regionCode=DE&eventType=completed&type=video&publishedAfter=2021-02-05T00:00:00Z&key={KEY}

但这包括直播,我想将它们从搜索中删除。直播一直LIVE在视频标题中,也许这有帮助。我也尝试使用q,但我总是得到 0 个搜索结果。

标签: google-apiyoutube-apiyoutube-data-apigoogle-api-python-client

解决方案


简短的回答如下:您必须手动过滤掉从Search.listAPI 端点获得的每个结果集中的实时流视频。

较长的答案如下:

当且仅当该视频附加了属性时,给定的视频才是实时流liveStreamingDetails

我强烈建议您阅读我最近的一个答案,该答案详细说明了针对此问题的 Python 解决方案,函数get_non_livestream_videos

def get_non_livestream_videos(youtube, video_ids):
    assert len(video_ids) <= 50
    if not video_ids: return []

    response = youtube.videos().list(
        fields = 'items(id,liveStreamingDetails)',
        part = 'id,liveStreamingDetails',
        maxResults = len(video_ids),
        id = ','.join(video_ids),
    ).execute()

    items = response.get('items', [])
    assert len(items) <= len(video_ids)

    not_live = lambda video: \
        not video.get('liveStreamingDetails')
    video_id = lambda video: video['id']

    return map(video_id, filter(not_live, items))

如果您有视频 ID 列表,video_ids则此函数调用Videos.listAPI 端点以确定liveStreamingDetails每个相应视频的属性是否存在。任何具有此类属性的视频都会从视频 ID 的结果列表中过滤掉。

请注意,上面我使用fields请求参数从 API 中仅获取实际需要的信息。

另请注意,使用的先决条件get_non_livestream_videos是其列表参数video_ids最多为 50 个元素。

使用此函数时,这不是实际的限制,因为它应该用于从分页 API 结果集中获得的视频 ID 列表。(Search.list返回最多包含 50 个项目的分页结果集。)


上面指出的解决方案从视频 ID 列表中排除所有即将播出、正在直播已完成直播的视频。

请注意,与已完成的直播对应的视频也被排除在外。

现在,如果您不希望将此类视频从结果集中排除(即您需要排除仅与即将播出或当前直播的视频对应的视频),那么您的查询有一个更简单的解决方案:

Search resource端点返回的对象Search.list提供以下属性:

snippet.liveBroadcastContent(细绳)

指示资源是否video具有channel直播内容。有效的属性值为upcominglivenone

对于video资源,值为upcoming表示该视频为尚未开始的直播,值为live表示该视频为活动直播。对于channel资源,值为upcoming表示该频道有一个尚未开始的预定广播,而值为live表示该频道有一个活跃的直播。

Search.list因此,您可以从查询中手动过滤掉具有snippet.liveBroadcastContent不同价值的视频,none如下所示:

not_live = lambda item: \
    item['snippet']['liveBroadcastContent'] == 'none'

request = youtube.search().list(
    fields = 'nextPageToken,items(id,snippet)',
    publishedAfter = '2021-02-05T00:00:00Z',
    channelId = 'UCZMsvbAhhRblVGXmEXW8TSA',
    part = 'id,snippet',
    order = 'viewCount',
    regionCode = 'DE',
    maxResults = 50,
    type = 'video'
)
videos = []

while request:
    response = request.execute()
    items = response.get('items', [])
    videos.extend(filter(not_live, items))
    request = youtube.search().list_next(
        request, response)

一个重要说明:上面的解决方案很简单,但受到以下channelId请求参数规范的限制Search.list

channelId(细绳)

channelId参数指示 API 响应应仅包含通道创建的资源。

注意:channelId如果您的请求为参数指定了一个值并将type参数值设置为,则搜索结果限制为最多 500 个视频video,但它不会同时设置forContentOwnerforDeveloperforMine过滤器之一。

因此,上面的分页循环,在 提供的结果集上Search.list,将导致videos最多 500 个元素的列表。


推荐阅读