如何通过API获取YouTube直播实时互动及赞/踩数据(Node.js无库实现)
基于Node.js无库获取YouTube直播互动及赞踩数据
核心思路
YouTube直播的聊天消息、赞/踩及观看数据分散在不同API端点,你需要同时调用两类接口:一类用于拉取实时聊天,另一类用于获取直播状态统计(含赞踩、在线人数等),通过轮询或循环请求实现实时更新。
分步实现
1. 从直播页面提取关键参数
首先需要从直播页面HTML中抓取videoId、innertubeApiKey等核心参数,这些是后续调用API的必要凭证:
const http = require('http'); function getLivePageParams(liveUrl) { return new Promise((resolve, reject) => { http.get(liveUrl, (res) => { let pageHtml = ''; res.on('data', chunk => pageHtml += chunk); res.on('end', () => { // 正则匹配所需参数 const apiKeyMatch = pageHtml.match(/"innertubeApiKey":"([^"]+)"/); const videoIdMatch = pageHtml.match(/"videoId":"([^"]+)"/); const playerRespMatch = pageHtml.match(/"playerResponse":({.*?}),/s); if (!apiKeyMatch || !videoIdMatch || !playerRespMatch) { return reject(new Error('无法从页面提取必要参数')); } resolve({ apiKey: apiKeyMatch[1], videoId: videoIdMatch[1], playerResponse: JSON.parse(playerRespMatch[1]) }); }); }).on('error', reject); }); }
2. 获取实时赞/踩及观看数据
使用提取到的参数调用YouTube的视频统计接口,该接口返回赞数、踩数(若未隐藏)、实时在线观看人数等数据:
function getLiveStats(apiKey, videoId) { return new Promise((resolve, reject) => { const reqUrl = `http://www.youtube.com/youtubei/v1/video/get_video_info?key=${apiKey}&video_id=${videoId}&cpn=temp&el=detailpage`; http.get(reqUrl, (res) => { let respData = ''; res.on('data', chunk => respData += chunk); res.on('end', () => { const parsedParams = new URLSearchParams(respData); const playerResp = JSON.parse(parsedParams.get('player_response')); const stats = { 观看总数: playerResp.videoDetails.viewCount, 点赞数: playerResp.videoDetails.likes, 点踩数: playerResp.videoDetails.dislikes || null, // 部分直播会隐藏踩数 实时在线人数: playerResp.playabilityStatus.liveStreamData?.concurrentViewers || null }; resolve(stats); }); }).on('error', reject); }); }
3. 实时拉取聊天消息(补充原有逻辑)
原有聊天接口需要continuationToken来续获取新消息,该参数可从页面初始数据中提取,之后循环请求即可:
function getLiveChat(apiKey, continuationToken) { return new Promise((resolve, reject) => { const postBody = JSON.stringify({ context: { client: { clientName: 'WEB', clientVersion: '2.20240520.01.00' } }, continuation: continuationToken }); const reqOptions = { hostname: 'www.youtube.com', path: `/youtubei/v1/live_chat/get_live_chat?key=${apiKey}`, method: 'POST', headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(postBody) } }; const req = http.request(reqOptions, (res) => { let respData = ''; res.on('data', chunk => respData += chunk); res.on('end', () => { const chatResp = JSON.parse(respData); const newContinuation = chatResp.continuationContents.liveChatContinuation.continuations[0].invalidationContinuationData.continuation; const newMessages = chatResp.continuationContents.liveChatContinuation.actions .filter(action => action.addChatItemAction) .map(action => action.addChatItemAction.item.liveChatTextMessageRenderer); resolve({ newMessages, newContinuation }); }); }); req.on('error', reject); req.write(postBody); req.end(); }); }
4. 整合实现实时监控
通过定时器轮询统计数据,同时循环拉取聊天消息,实现完整的实时监控:
async function startLiveMonitoring(liveUrl) { const pageParams = await getLivePageParams(liveUrl); let chatContinuation = pageParams.playerResponse.continuationContents?.liveChatContinuation?.continuations[0].invalidationContinuationData.continuation; // 每5秒更新一次赞踩及观看数据 setInterval(async () => { const stats = await getLiveStats(pageParams.apiKey, pageParams.videoId); console.log('当前直播统计:', stats); }, 5000); // 持续拉取聊天消息 async function chatLoop() { const { newMessages, newContinuation } = await getLiveChat(pageParams.apiKey, chatContinuation); chatContinuation = newContinuation; if (newMessages.length > 0) { console.log('新聊天消息:', newMessages.map(msg => ({ 用户名: msg.authorName.simpleText, 内容: msg.message.runs[0].text }))); } setTimeout(chatLoop, 1000); // 每秒请求一次,可根据实际情况调整频率 } chatLoop(); } // 调用示例 startLiveMonitoring('https://www.youtube.com/watch?v=你的直播ID');
注意事项
- YouTube的API端点和参数可能随时变更,若请求失败需重新检查页面结构和请求格式
- 频繁请求可能触发限流,建议合理调整轮询间隔,避免IP被封禁
- 部分直播会隐藏点踩数据,此时
点踩数字段会返回null - 必要时可在请求头中添加
User-Agent等字段模拟浏览器请求,避免被拒绝
内容的提问来源于stack exchange,提问作者Yovel Nehmady
相关产品推荐
相关产品推荐

