如何通过YouTube Data API批量添加订阅页未看视频至稍后观看
Hey there! Let's break down how to get this working—whether you want a quick browser script (no API hoops) or the proper YouTube Data API implementation you're trying to use. I’ve messed around with similar scripts for YouTube, so here’s what you need to know.
Quick Browser Script (No API Required)
If you just need a temporary solution to run directly in your browser’s console on the subscriptions page, this is the fastest way. It simulates clicking the "Save to Watch Later" option for every unwatched video:
First, we’ll scroll to load all lazy-loaded videos, then batch process them:
// Scroll to load all unwatched videos (adjust timeouts if needed for slow internet) function scrollToLoadAll() { return new Promise((resolve) => { const scrollInterval = setInterval(() => { window.scrollTo(0, document.body.scrollHeight); const lastHeight = document.body.scrollHeight; setTimeout(() => { if (document.body.scrollHeight === lastHeight) { clearInterval(scrollInterval); resolve(); } }, 1000); }, 1500); }); } // Batch add unwatched videos to Watch Later async function batchAddToWatchLater() { await scrollToLoadAll(); // Grab all unwatched videos (marked by the absence of the "is-watched" attribute) const unWatchedVideos = document.querySelectorAll('ytd-grid-video-renderer:not([is-watched])'); console.log(`Found ${unWatchedVideos.length} unwatched videos to process`); for (const video of unWatchedVideos) { try { // Open the "More actions" menu const moreBtn = video.querySelector('#button[aria-label="More actions"]'); if (!moreBtn) continue; moreBtn.click(); // Wait for the menu to render await new Promise(resolve => setTimeout(resolve, 500)); // Click "Save to Watch Later" const watchLaterOption = document.querySelector('yt-formatted-string[aria-label="Save to Watch Later"]'); if (watchLaterOption) { watchLaterOption.click(); console.log(`Added: ${video.querySelector('#video-title').innerText}`); } // Close the menu before moving to the next video await new Promise(resolve => setTimeout(resolve, 300)); document.body.click(); } catch (err) { console.error(`Skipping video due to error:`, err); } } console.log('Batch add complete! 🎉'); } // Run the script batchAddToWatchLater();
Notes for this method:
- YouTube updates its DOM structure occasionally, so if selectors break, inspect the page to find new ones.
- Don’t run this too frequently—YouTube might flag your actions as automated and temporarily restrict access.
- Adjust the timeout values if you have slow internet (give more time for videos to load and menus to open).
Using the YouTube Data API (Insert Method)
If you want a more robust solution (and are running into issues with the API), let’s fix those common pain points. The main hurdles are authentication, finding the Watch Later playlist ID, and avoiding quota limits.
Step 1: Set Up API Access
First, you’ll need to:
- Go to the Google Cloud Console, create a project, and enable the YouTube Data API v3.
- Create OAuth 2.0 credentials (since you’re modifying user-specific data).
- Make sure your OAuth scope includes
https://www.googleapis.com/auth/youtube(oryoutube.force-sslfor read/write access).
Step 2: Working Code Implementation
This script will authenticate the user, fetch their Watch Later playlist ID, then batch add unwatched videos via the API:
// Reuse the scroll function from the previous script to load all videos function scrollToLoadAll() { return new Promise((resolve) => { const scrollInterval = setInterval(() => { window.scrollTo(0, document.body.scrollHeight); const lastHeight = document.body.scrollHeight; setTimeout(() => { if (document.body.scrollHeight === lastHeight) { clearInterval(scrollInterval); resolve(); } }, 1000); }, 1500); }); } // Fetch the user's Watch Later playlist ID async function getWatchLaterId(accessToken) { const res = await fetch('https://www.googleapis.com/youtube/v3/channels?part=contentDetails&mine=true', { headers: { 'Authorization': `Bearer ${accessToken}` } }); const data = await res.json(); return data.items[0].contentDetails.relatedPlaylists.watchLater; } // Add a single video to Watch Later via API async function addVideoToPlaylist(accessToken, playlistId, videoId) { const res = await fetch('https://www.googleapis.com/youtube/v3/playlistItems', { method: 'POST', headers: { 'Authorization': `Bearer ${accessToken}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ snippet: { playlistId: playlistId, resourceId: { kind: 'youtube#video', videoId: videoId } } }) }); return res.json(); } // Batch process videos using the API async function batchAddViaAPI() { // Handle OAuth authentication (use Google's gapi library for browser-based auth) // Example auth flow: // await gapi.auth2.getAuthInstance().signIn(); // const accessToken = gapi.auth2.getAuthInstance().currentUser.get().getAuthResponse().access_token; // Replace with your actual access token after auth const accessToken = 'YOUR_VALID_ACCESS_TOKEN'; const watchLaterId = await getWatchLaterId(accessToken); // Load all videos and get their IDs await scrollToLoadAll(); const unWatchedVideos = document.querySelectorAll('ytd-grid-video-renderer:not([is-watched])'); const videoIds = Array.from(unWatchedVideos).map(video => { const url = video.querySelector('#video-title').href; return new URL(url).searchParams.get('v'); }); console.log(`Processing ${videoIds.length} videos via API`); // Batch insert with delays to avoid quota/rate limits for (const id of videoIds) { try { await addVideoToPlaylist(accessToken, watchLaterId, id); console.log(`Added video ID: ${id}`); // Add a 1-second delay to stay under rate limits await new Promise(resolve => setTimeout(resolve, 1000)); } catch (err) { console.error(`Failed to add ${id}:`, err); } } console.log('API batch operation complete!'); } // Run after setting up auth // batchAddViaAPI();
Common API Issues & Fixes
- Authorization Errors: Double-check your OAuth scope—you need write access to modify playlists. Also, ensure the user has granted permission to your app.
- Quota Limits: The YouTube API uses a quota system (10,000 units/day by default). Each
playlistItems.insertcall uses 50 units, so you can add ~200 videos/day. If you need more, request a quota increase in the Google Cloud Console. - CORS Errors: If running from the browser console, direct
fetchcalls might hit CORS issues. Use Google’s officialgapilibrary instead, or wrap the script in a browser extension (which bypasses CORS restrictions). - Duplicate Videos: The API will throw an error if the video is already in Watch Later. To avoid this, you can pre-check with a
playlistItems.listcall (but this uses additional quota).
内容的提问来源于stack exchange,提问作者Denis Davydenko

