You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Puppeteer与Node.js开发YouTube搜索爬虫时无限滚动失效问题

解决YouTube搜索结果爬虫无法获取全部内容的问题

你的代码存在几个核心问题,导致只能爬取部分结果:

  • 先执行爬取再滚动页面,抓取的只是初始加载的少量内容,滚动后加载的新内容完全没被处理
  • 原滚动函数没适配YouTube的动态加载特性,滚动一次后可能新内容还没渲染完成就停止了,而且页面高度会随新内容加载持续增加,原逻辑会提前终止滚动
  • 页面跳转时未等待完全加载,初始内容可能还没渲染好就开始爬取

下面是修改后的完整代码,解决这些问题:

const puppeteer = require('puppeteer');

async function parseSearch(page) {
    // 等待目标元素加载完成,避免DOM未渲染就爬取
    await page.waitForSelector(".text-wrapper.style-scope.ytd-video-renderer");
    
    const search = await page.evaluate(() => {
        const searchResults = document.querySelectorAll(".text-wrapper.style-scope.ytd-video-renderer");
        const lists = [];
        
        searchResults.forEach(element => {
            const vidName = element.querySelector("h3");
            const channel = element.querySelector("a.yt-simple-endpoint.style-scope.yt-formatted-string");
            
            lists.push({
                video_name: vidName?.innerText || '无标题', // 增加容错,避免元素不存在报错
                channel_name: channel?.innerText || '未知频道' // 用innerText代替innerHTML,避免获取HTML标签
            });
        });
        
        return lists;
    });
    
    return search;
}

async function autoScroll(page) {
    await page.evaluate(async () => {
        let lastScrollHeight = document.body.scrollHeight;
        
        while (true) {
            window.scrollTo(0, document.body.scrollHeight);
            // 等待新内容加载,可根据网络情况调整等待时长
            await new Promise(resolve => setTimeout(resolve, 1000));
            
            const newScrollHeight = document.body.scrollHeight;
            // 滚动高度不再变化时,说明没有新内容了
            if (newScrollHeight === lastScrollHeight) {
                break;
            }
            lastScrollHeight = newScrollHeight;
        }
    });
}

(async () => {
    const browser = await puppeteer.launch({ headless: false });
    const page = await browser.newPage();
    
    // 等待页面网络空闲,确保初始内容加载完成
    await page.goto("https://www.youtube.com/results?search_query=programming", {
        waitUntil: 'networkidle2'
    });
    
    // 先滚动到底部加载全部内容
    await autoScroll(page);
    // 再爬取所有结果
    const result = await parseSearch(page);
    
    console.log(`共爬取到${result.length}条结果:`);
    console.log(result);
    
    await browser.close();
})();

console.log("END");

关键修改说明:

  • 调整执行顺序:先滚动加载全部内容,再调用爬取函数
  • 优化滚动逻辑:循环滚动直到页面高度不再变化,确保所有动态内容加载完成,每次滚动后等待1秒让内容渲染
  • 增加等待机制:page.waitForSelector确保目标元素存在后再爬取,page.goto的waitUntil参数保证初始页面加载完成
  • 容错处理:用可选链?.避免元素不存在时抛出错误,给字段设置默认值
  • 修正文本获取:用innerText代替innerHTML获取频道名称,避免拿到多余HTML标签

内容的提问来源于stack exchange,提问作者Vishnu Nair

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 10:50:37