如果您需要获取给定频道的所有视频列表(由其 ID 标识),例如CHANNEL_ID
--,那么你必须进行如下操作:
Step 1:查询Channels.list带参数的 API 端点id=CHANNEL_ID
用于从API获取该频道上传播放列表的 ID:
response = youtube.channels().list(
id = CHANNEL_ID,
part = 'contentDetails',
fields = 'items(contentDetails(relatedPlaylists(uploads)))',
maxResults = 1
).execute()
uploads_id = response \
['contentDetails'] \
['relatedPlaylists'] \
['uploads']
上面的代码应该只运行一次来获取上传播放列表 ID,如下所示uploads_id
,那么该 ID 应根据需要多次使用。
通常,频道 ID 与其对应的上传播放列表 ID 的关联关系为s/^UC([0-9a-zA-Z_-]{22})$/UU\1/
.
Step 2:使用之前获得的上传播放列表ID——我们来命名它UPLOADS_ID
--, 查询PlaylistItems.listAPI端点用于获取该播放列表的所有视频ID的列表:
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)
运行上面的代码后,列表videos
将包含在由以下标识的频道上上传的所有视频的 IDCHANNEL_ID
.
Step 3:查询Videos.listAPI端点用于获取statistics您感兴趣的每个视频的信息(即对象):
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']
)
)
请注意上面的代码,以防列表videos
有长度N
,减少调用次数Videos.list
from N
to math.floor(N / 50) + (1 if N % 50 else 0)
。这是因为参数id of Videos.list
端点可以指定为以逗号分隔的视频 ID 列表(此类列表中的 ID 数量最多可为 50)。
另请注意,上面的每段代码都使用fields请求参数用于从调用的 API 端点仅获取实际使用的信息。
我还必须提到,根据YouTube 的员工,设置了上限 20000按设计通过以下方式返回的商品数量PlaylistItems.list
端点。这是不幸的,但却是事实。