使用Google YouTube v3 API获取用户频道视频:Node.js脚本报错排查
解决YouTube API videos.list报错及获取用户所有上传视频的正确方案
错误原因
- API Key不支持
mine: true参数:API Key仅能请求公开的YouTube数据,无法验证用户身份,因此API不认可你传入的mine: true参数,直接判定未指定合法过滤器。 - 用错了API接口:
videos.list并不适合批量获取用户所有上传视频,正确的操作路径是先获取用户的「上传专属播放列表ID」,再遍历该播放列表的内容。
修复步骤及完整代码
1. 修正授权流程
你之前把用户输入的授权码(authorization code)直接当成access token使用,这是错误的。需要用授权码去换取有效的access token和refresh token。
2. 正确的API调用流程
要获取用户所有上传视频,需分两步执行:
- 调用
channels.list接口,获取用户的「上传播放列表ID」 - 调用
playlistItems.list接口,分页遍历该播放列表的所有视频项(自动处理请求频率限制)
完整修正代码
const readlineSync = require('readline-sync'); const { google } = require('googleapis'); const axios = require('axios'); // 需安装axios用于换取token // 填入你的Google Cloud项目信息 const YOUR_CLIENT_ID = '你的客户端ID'; const YOUR_CLIENT_SECRET = '你的客户端密钥'; const REDIRECT_URI = 'http://localhost:3000/oauth2callback'; // 引导用户授权,获取授权码 console.log('请访问以下链接完成授权:'); console.log(`https://accounts.google.com/o/oauth2/auth?client_id=${YOUR_CLIENT_ID}&response_type=code&scope=https://www.googleapis.com/auth/youtube.readonly&redirect_uri=${encodeURIComponent(REDIRECT_URI)}`); const authCode = readlineSync.question('请输入授权码:'); // 用授权码换取access token和refresh token async function getAccessToken(code) { const response = await axios.post('https://oauth2.googleapis.com/token', { code, client_id: YOUR_CLIENT_ID, client_secret: YOUR_CLIENT_SECRET, redirect_uri: REDIRECT_URI, grant_type: 'authorization_code' }); return response.data; } // 获取用户所有上传视频的核心逻辑 async function fetchAllUserVideos(auth) { const youtube = google.youtube({ version: 'v3', auth }); // 第一步:获取用户的上传播放列表ID const channelRes = await youtube.channels.list({ part: 'contentDetails', mine: true }); const uploadsPlaylistId = channelRes.data.items[0].contentDetails.relatedPlaylists.uploads; console.log(`用户上传播放列表ID:${uploadsPlaylistId}`); // 第二步:分页遍历播放列表,获取所有视频 let nextPageToken = null; let allVideos = []; do { const playlistRes = await youtube.playlistItems.list({ part: 'snippet,contentDetails', playlistId: uploadsPlaylistId, maxResults: 50, // 单次请求最大返回数(API上限) pageToken: nextPageToken }); allVideos = [...allVideos, ...playlistRes.data.items]; nextPageToken = playlistRes.data.nextPageToken; // 处理请求频率限制,分页后休眠1秒 if (nextPageToken) { await new Promise(resolve => setTimeout(resolve, 1000)); } } while (nextPageToken); // 输出视频信息 console.log(`共获取到${allVideos.length}个视频:`); allVideos.forEach((video, index) => { console.log(`\n视频${index + 1}:`); console.log(`视频ID:${video.contentDetails.videoId}`); console.log(`标题:${video.snippet.title}`); console.log(`描述:${video.snippet.description.substring(0, 100)}...`); // 截取前100字符避免输出过长 console.log(`缩略图(默认尺寸):${video.snippet.thumbnails.default?.url}`); }); } // 执行完整流程 getAccessToken(authCode) .then(tokenData => { const auth = new google.auth.OAuth2(YOUR_CLIENT_ID, YOUR_CLIENT_SECRET, REDIRECT_URI); auth.setCredentials({ access_token: tokenData.access_token, refresh_token: tokenData.refresh_token }); return fetchAllUserVideos(auth); }) .catch(err => { console.error('执行出错:', err); });
额外说明
- 安装依赖:运行
npm install readline-sync googleapis axios完成依赖安装 - 权限范围:使用
https://www.googleapis.com/auth/youtube.readonly权限足够获取用户自己的所有视频信息 - 频率限制:代码中加入了分页后的1秒休眠,若仍触发限制,可根据API返回的
Retry-After响应头调整休眠时长
内容的提问来源于stack exchange,提问作者Martin
相关产品推荐
相关产品推荐

