使用YouTube Data API时如何避免视频信息获取的遗漏?

2024-01-25

假设/我想要实现的目标

我想使用YouTube Data API V3来无遗漏地获取视频ID,并找出问题的原因是在代码中还是在YouTube(API端)的视频设置中。

Problem

以下代码用于从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 个视频(日本标准时间上午 10:30)。

补充信息

・Python 3.9.0

・YouTube 数据 API v3


你必须承认Search.list https://developers.google.com/youtube/v3/docs/search/listAPI端点没有清晰的行为。这意味着你不应期望精确的结果从中。谷歌并没有记录这种行为,但这个论坛有很多来自经历过这种行为的用户的帖子。

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

步骤一:获取频道上传播放列表ID。

调用Channels.list https://developers.google.com/youtube/v3/docs/channels/listAPI端点,通过其请求参数进行查询id https://developers.google.com/youtube/v3/docs/channels/list#id设置为您感兴趣的频道的 ID(或者,使用其请求参数mine https://developers.google.com/youtube/v3/docs/channels/list#mine set to true) 用于获取该频道的上传播放列表 ID,contentDetails.relatedPlaylists.uploads https://developers.google.com/youtube/v3/docs/channels#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 https://developers.google.com/youtube/v3/docs/playlistItems/listAPI端点,通过其请求参数进行查询playlistId https://developers.google.com/youtube/v3/docs/playlistItems/list#playlistId设置为从获取的IDget_channel_uploads_playlist_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 的 Python API 客户端库 https://github.com/googleapis/google-api-python-client(像你一样做),API结果集分页 https://developers.google.com/youtube/v3/guides/implementation/pagination非常简单:只需使用list_next与相应分页 API 端点对应的 Python API 对象的方法(如上所示):

request = API_OBJECT.list(...)

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

另请注意,上面我使用了两次fields https://developers.google.com/youtube/v3/getting-started#fields请求参数。这是一个很好的做法:仅从 API 询问实际使用的信息。

还有一个重要的注意事项:PlaylistItems.list端点不会返回对应的项目private使用 API 密钥调用时频道的视频。当您的youtube对象是通过调用函数构造的apiclient.discovery.build将参数传递给它后developerKey.

PlaylistItems.list仅将与私有视频对应的项目返回给频道所有者。当youtube对象是通过调用函数构造的apiclient.discovery.build将参数传递给它后credentials and if credentials指拥有相应播放列表的频道。

附加重要说明:根据谷歌员工 https://issuetracker.google.com/issues/166292064#comment2,设置了上限 20000按设计通过以下方式返回的商品数量PlaylistItems.list查询给定频道的上传播放列表时的端点。这是不幸的,但却是事实。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用YouTube Data API时如何避免视频信息获取的遗漏? 的相关文章

随机推荐

  • 从 Java 调用 Python

    我想打电话给python来自 Java 的脚本 我的python版本是2 5 Java版本是6 我当前的代码 try Process p Runtime getRuntime exec path dirs file py p waitFor
  • 尝试使用 C# 代码将数据输入到访问文件时出现无效的 Sql 语句错误[重复]

    这个问题在这里已经有答案了 我的错误是 System Data OleDb OleDbException 无效的 SQL 语句 应为 DELETE INSERT PROCEDURE SELECT 或 UPDATE 这是我的代码 我检查以确保
  • 在 Eclipse 中隐藏状态栏或进度栏

    如何隐藏 Eclipse 中的状态栏 我指的是底部的那个 其中还显示 进度 状态 它非常分散注意力 因为它一直在做某事 我看了一下这个问题 https stackoverflow com questions 5645495 how to h
  • 使用 Mockito 的 ArgumentCaptor 类来匹配子类

    下面的代码显示了我的问题 实际上 我尝试使用 Mockito 的 ArgumentCaptor 来验证某个具体类是否调用过一次方法 如果可能的话 我想在这里使用 ArgumentCaptor 但我开始怀疑我需要使用自定义 ArgumentM
  • 本机窗口queueBuffer函数不渲染来自Stagefright解码器的输出

    我将 SurfaceView 表面从 Java 传递到 JNI 在 JNI 中我从该表面获取本机窗口 Stagefright从 mp4 文件中解码 h264 帧 在解码过程中我调用ANativeWindow queueBuffer 为了发送
  • Rails 4:如何使用includes() 和where() 来检索关联对象

    我不知道如何使用 where 方法来检索关联的模型数据 在此示例中 项目属于用户 class Project lt ActiveRecord Base belongs to user has many videos end class Us
  • 为什么 GCC 的 -Wconversion 对于 char 和 unsigned char 的行为不同?

    Consider U8 foo U8 x U8 y return x y 如果 x 和 y 的类型 U8 是 char 或 unsigned char GCC 的 Wconversion 的行为会有所不同 gcc Wconversion c
  • 循环绘制子图

    z A 0 3618426 0 36146951 B 1 8908799 1 904695 C 2 1813462e 08 2 1833622e 08 D 0 89925492 0 89953589 E 2 6356747 2 631791
  • 如何使用 Excel VBA 单击网页上的链接?

    我正在编写 VBA 代码来从用户那里获取股票代码 导航到网站 输入股票代码并单击相应的链接 我研究了这个StackOverflow 问题和回复 https stackoverflow com questions 21002756 how t
  • Java:HashSet 与 HashMap

    我有一个程序正在处理巨大的数据集 对象最好存储在散列实现的容器中 因为程序不断在容器中寻找对象 第一个想法是使用HashMap 因为这个容器的get和remove方法更适合我需要的用途 但是 我发现 HashMap 的使用非常消耗内存 这是
  • 在运行时更改.dll

    我有一个巨大的应用程序 我的解决方案的一个项目在其中生成报告 我想添加新报告 更新报告 而不构建我的项目 只需添加 dll文件 我读到Assembly and AppDomain 但我不知道为新报告添加新的 dll 以及如何在运行时更新旧报
  • 我的图像处理项目的研究领域是什么?

    在我的最后一年项目中 我正在做一个车辆细节修改系统 系统应该能够完成以下任务 我使用的是从固定距离 例如 5m 拍摄的车辆尺寸图像 并存储不同的颜色和边缘图像我是我的应用程序 这是基本思想 检测车辆的轮胎和合金轮辋 检测并测量已安装轮辋的轮
  • Selenium - 如何获取窗口中打开的选项卡数量?

    我的测试用例 打开浏览器并访问 URL 单击主页上的链接 gt 这将打开一个新窗口 新选项卡 返回主页 单击另一个链接 确保步骤 2 中先前打开的子窗口 子选项卡上显示新内容 我可以通过获取窗口句柄的计数来检查打开的窗口数量 并断言它等于
  • Java中如何模拟文件IO?

    我怎样才能创建一个类MockFile模仿java io Filew r t 文件读写 我到处都用我自己的方法而不是new FileInputStream and new FileOutputStream 所以这部分没有问题 我总是委托给适当
  • 获取参数的调用变量名

    关于这个问题从调用方法中获取参数名称 https stackoverflow com questions 15205457 get the name of parameters from a calling method and 在 C 中
  • R 中没有重复的 Left_Join

    我想做一种vlookup 正如您所知 Excel vlookup 函数从数据中获取第一个值 另一方面 left join 函数的工作原理类似 但是 当第一个数据在查找值上不唯一时 left join 函数会重复 de 值 我想对 Excel
  • gradle 将外部插件的 jar 存储在哪里?

    我正在使用一个名为 jsonschema2pojo 的外部 gradle 插件 为此 我在 build gradle 文件中添加了以下代码 我可以成功使用该插件 但我找不到必须下载并存储在某处的 jar 在哪里可以找到为外部插件下载的 ja
  • 如何仅在 bash 中存在脚本时才执行该脚本?

    我想知道是否有一种更简单的方法可以仅在该脚本存在时才在 bash 中执行该脚本 我想要的相当于 if x name then name fi or x name name 我正在寻找的是类似的东西 exec if exist name 这消
  • Python-如何使用 re 来匹配整个字符串[重复]

    这个问题在这里已经有答案了 我正在验证用户输入的文本 以便它只接受字母而不接受数字 到目前为止 当我输入数字 例如 56 时 我的代码工作正常 它警告我应该只输入字母 而当我输入字母时 它不会返回任何内容 就像它应该做的那样 我的问题是 当
  • 使用YouTube Data API时如何避免视频信息获取的遗漏?

    假设 我想要实现的目标 我想使用YouTube Data API V3来无遗漏地获取视频ID 并找出问题的原因是在代码中还是在YouTube API端 的视频设置中 Problem 以下代码用于从YouTube Data API获取视频信息