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

使用Puppeteer抓取动态加载内容失败,需处理加载更多按钮

Puppeteer爬动态内容失败+处理「加载更多」按钮的解决办法

问题根源

  • 你代码里的new Promise(r => setTimeout(r, 5000))没加await,等于白等——代码不会暂停,直接往下执行,这时候动态内容还没加载出来,自然抓不到。
  • 没处理「Cargar más」按钮的循环点击,只能拿到初始加载的少量内容,分页的文章链接根本没机会获取。

修正后的完整代码

async function getLinksFromBase(category) {
  const urlBase = 'https://xepelin.com/blog/';
  const browser = await puppeteer.launch({
    headless: 'new', // 用新版无头模式,兼容性更好
    args: ['--no-sandbox', '--disable-setuid-sandbox', '--start-maximized']
  });
  const page = await browser.newPage();
  
  // 设置桌面端视口,避免网站加载移动端布局
  await page.setViewport({ width: 1200, height: 800 });

  // 跳转到目标页面,等待网络空闲再继续(确保初始内容加载完)
  await page.goto(urlBase + category, { waitUntil: 'networkidle2' });

  // 循环点击「加载更多」按钮,直到按钮消失
  while (true) {
    try {
      // 等加载更多按钮出现,超时10秒就退出
      const loadMoreBtn = await page.waitForSelector('button:has-text("Cargar más")', { timeout: 10000 });
      // 点击按钮(用evaluate避免元素不可交互的问题)
      await page.evaluate(btn => btn.click(), loadMoreBtn);
      // 等新文章加载出来:对比当前文章数量,等数量增加再继续
      const prevCount = await page.$$eval('.blog-posts .post-item', items => items.length);
      await page.waitForFunction(
        count => document.querySelectorAll('.blog-posts .post-item').length > count,
        {},
        prevCount
      );
    } catch (err) {
      // 按钮找不到或者超时,说明没有更多内容了,退出循环
      break;
    }
  }

  // 只抓博客文章的链接,过滤掉无关的a标签
  const hrefs = await page.$$eval('.blog-posts .post-item a', anchors => {
    return anchors.map(anchor => anchor.href).filter(href => href.includes('/blog/'));
  });

  await browser.close();
  return hrefs;
}

关键修改说明

  1. 修复等待逻辑:

    • 删掉没用的setTimeout,改用page.goto的waitUntil: 'networkidle2',等页面网络请求基本结束再继续,比固定等几秒靠谱。
    • 如果确实需要额外等待,用await page.waitForTimeout(3000)(不过这个方法已经被标记为过时,更推荐等特定元素出现)。
  2. 处理加载更多按钮:

    • 用while(true)循环,一直检查按钮是否存在,直到按钮消失就停。
    • 每次点击后,等新的文章加载出来再继续,避免还没加载完就又点按钮。
  3. 精准抓取目标链接:

    • 不再抓所有a标签,只定位到博客文章容器里的链接,还加了过滤确保只留博客相关的,减少无效数据。
  4. 优化无头模式配置:

    • 用headless: 'new',这是Puppeteer新版本推荐的,比旧无头模式更稳定。
    • 加了--start-maximized和setViewport,确保网站加载桌面端布局,避免移动端内容不一样。

调试小技巧

  • 把headless改成false,打开浏览器窗口看页面加载情况,确认动态内容是不是真的加载出来了。
  • 加一行page.on('console', msg => console.log('页面日志:', msg.text())),看看页面有没有JS报错,有时候报错会导致内容加载失败。
  • 点击按钮后可以加个短等待,比如await page.waitForTimeout(1000),模拟真实用户的操作节奏,避免触发反爬。

内容的提问来源于stack exchange,提问作者Diego Collao Alcayaga

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 17:17:51