我们正在尝试获取频道中的所有视频,例如this。该列表有 291k 个视频,我们计算出该频道的频道 id(并将 id 中的第二个字母“C”替换为“U”),并尝试此代码,一次迭代超过 50 个视频。我们只能获取大约 20k 个视频,不会更多。您知道如何解决此问题并获取此频道中的所有 291k 视频吗?检查了多个视频数量较多的频道,都有同样的问题。
api_key = "my Google YouTube API V3 key"
from googleapiclient.discovery import build
youtube = build('youtube', 'v3', developerKey=api_key)
def get_channel_videos():
videos = []
next_page_token = None
while 1:
res = youtube.playlistItems().list(playlistId="UU...",
part='snippet',
maxResults=50,
pageToken=next_page_token).execute()
videos += res['items']
next_page_token = res.get('nextPageToken')
if next_page_token is None:
break
return videos
videos = get_channel_videos()
with open("video.txt", "a") as myfile:
for video in videos:
myfile.write(f"{video['snippet']['resourceId']['videoId']} => {video['snippet']['title']}\n")
print(f"Total video count => {len(videos)}")
一次迭代 50 多个视频。我们只能获取大约 20k 视频,不会更多
毫不奇怪,考虑到 YouTube API 配额限制,详细信息请参阅“Youtube API 限制:如何计算 API 使用成本并修复超出的 API 配额”
您可以:
增量检索:如果您不需要一次检索所有视频,您可以考虑通过多次运行脚本来增量检索它们。您可以将
nextPageToken
值和检索到的视频信息存储在文件或数据库中,并在下次运行时从中断处继续检索过程。
API 密钥轮换:如果您有多个 API 密钥,您可以轮换它们以将 API 请求分布在不同的密钥上。这可以帮助您避免达到单个 API 密钥的配额限制。
最后一种方法如下所示:
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
# List of your Google YouTube API V3 keys
api_keys = ["my Google YouTube API V3 key 1", "my Google YouTube API V3 key 2", "etc."]
def build_youtube_service(api_key):
return build('youtube', 'v3', developerKey=api_key)
def get_channel_videos(api_keys):
videos = []
next_page_token = None
api_key_index = 0 # Start with the first API key
while True:
try:
# Build the YouTube service object with the current API key
youtube = build_youtube_service(api_keys[api_key_index])
res = youtube.playlistItems().list(playlistId="UU...",
part='snippet',
maxResults=50,
pageToken=next_page_token).execute()
videos += res['items']
next_page_token = res.get('nextPageToken')
if next_page_token is None:
break
except HttpError as e:
if e.resp.status in [403, 429]: # Quota error detected
print(f"Quota error with API key {api_keys[api_key_index]}, switching keys...")
api_key_index += 1 # Move to the next API key
if api_key_index >= len(api_keys): # Check if we've exhausted all API keys
print("All API keys have reached their quota limits.")
break
continue
else:
raise # Re-raise the exception if it's not a quota error
return videos
videos = get_channel_videos(api_keys)
with open("video.txt", "a") as myfile:
for video in videos:
myfile.write(f"{video['snippet']['resourceId']['videoId']} => {video['snippet']['title']}\n")
print(f"Total video count => {len(videos)}")