I’m working on a Puppeteer script to browse YouTube channels. My goal is to search for a channel, then pick a random video to watch. The script works fine until it tries to click a random video link.
I’ve tried different baseUrl values like ‘YouTube’ but no luck. Here’s a simplified version of my code:
async function clickRandomVideo(page) {
const result = await page.evaluate(() => {
const videoLinks = Array.from(document.querySelectorAll('a[href^="/watch"]'));
if (videoLinks.length > 0) {
const randomVideo = videoLinks[Math.floor(Math.random() * videoLinks.length)];
randomVideo.click();
return 'success';
}
return 'failed';
});
try {
await page.waitForNavigation({ waitUntil: 'networkidle0', timeout: 5000 });
} catch (e) {
console.error('Navigation timeout');
}
return result;
}
I’ve checked the page source and found that video links look like this:
<a href="/watch?v=abcdefghijk" class="video-title">
<h4>Video Title</h4>
<div class="video-info">
<span>1000 views</span>
<span>2 weeks ago</span>
</div>
</a>
I’ve tried using ‘/watch?v’ and ‘/watch’ as link patterns, but it’s not working. Any ideas on how to fix this?
I’ve encountered similar challenges with Puppeteer and YouTube. One effective solution I’ve found is to use the YouTube Data API instead of scraping. It’s more reliable and less prone to breaking when YouTube’s frontend changes.
A general approach involves obtaining an API key from the Google Developer Console, then using the API to fetch the channel’s uploads playlist and extract the video IDs. Once you have these IDs, you can select one at random and construct the URL accordingly.
This method is often faster, more stable, and compliant with YouTube’s terms of service. If you must stick with Puppeteer, try implementing delays between actions and using more robust selectors to boost reliability.
yo, ive run into this too. try using a different selector like ‘#thumbnail[href^="/watch"]’. youtube’s layout changes a lot, so u might need to update ur selectors sometimes. also, consider adding a small delay before clicking, like:
await page.waitForTimeout(1000);
await page.click('#thumbnail[href^=\"/watch\"]');
this might help with timing issues. good luck!
I’ve faced similar issues with Puppeteer and YouTube before. One thing that helped me was using a more specific selector for the video links. Instead of just ‘a[href^=“/watch”]’, try something like ‘a#video-title[href^=“/watch”]’ or ‘ytd-video-renderer a#video-title’. These tend to be more reliable.
Another approach that worked for me was to extract the video IDs first, then construct the full URL:
const videoIds = await page.evaluate(() => {
return Array.from(document.querySelectorAll('a#video-title'))
.map(el => el.href.split('v=')[1]);
});
const randomId = videoIds[Math.floor(Math.random() * videoIds.length)];
await page.goto(`https://www.youtube.com/watch?v=${randomId}`);
This method bypasses the need to click on the link directly, which can sometimes be unreliable due to YouTube’s dynamic content loading. Hope this helps!