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

如何解决Puppeteer访问重度脚本化网站的加载超时问题?

解决Puppeteer访问重度脚本化网站的超时问题

我明白你现在的困扰——用Puppeteer访问像香港讨论区这种塞满广告脚本、重度依赖JS的网站时,频繁碰到加载超时,调了waitUntil的各种参数也没效果。这些广告脚本一直在后台跑请求,导致networkidle状态永远没法达成,自然会超时。给你几个亲测有效的解决方案:

1. 拦截非必要请求,砍掉加载负担

广告、第三方统计、冗余的图片/视频资源是拖慢页面的核心,直接拦截它们能大幅减少页面需要加载的内容:

async function run() { 
  const browser = await puppeteer.launch({ args: ['--no-sandbox', '--disable-setuid-sandbox'] }); 
  const page = await browser.newPage(); 
  page.setViewport({ width: 1280, height: 2000 }); 

  // 开启请求拦截
  await page.setRequestInterception(true);
  page.on('request', (req) => {
    // 定义要拦截的资源类型和关键词
    const blockedTypes = ['image', 'stylesheet', 'font', 'media'];
    const blockedKeywords = ['ad', 'analytics', 'doubleclick', 'cdn.ad', 'video'];
    
    // 如果是拦截的类型或包含广告关键词,就终止请求
    if (blockedTypes.includes(req.resourceType()) || 
        blockedKeywords.some(keyword => req.url().toLowerCase().includes(keyword))) {
      req.abort();
    } else {
      req.continue();
    }
  });

  page.on('load', () => console.log('Page loaded!', page.url())); 
  // 后续的页面跳转和截图逻辑...
}

2. 放弃等网络空闲,改用等待核心元素加载

很多广告脚本会一直发请求,networkidle0或networkidle2永远不会触发。不如直接等待页面的核心元素加载完成,同时设置合理的超时兜底:

// 替换原来的page.goto逻辑,比如访问论坛列表页:
await page.goto('http://www.discuss.com.hk/forumdisplay.php?fid=215', {
  timeout: 60000, // 设置60秒超时,可根据情况调整
});
// 等待论坛帖子列表的核心容器加载(这里的选择器需要你根据页面实际情况调整)
await page.waitForSelector('#threadlisttableid', { timeout: 30000 });
await page.screenshot({ path: 'dis2.png' });

这样只要核心内容加载完毕,就可以继续操作,不用管后台的广告脚本瞎折腾。

3. 优化浏览器启动参数,减少后台开销

给Puppeteer的浏览器加一些优化参数,禁用不必要的功能,降低资源占用:

const browser = await puppeteer.launch({
  args: [
    '--no-sandbox',
    '--disable-setuid-sandbox',
    '--disable-dev-shm-usage', // 避免容器或低内存环境下的内存不足问题
    '--disable-gpu', // 禁用GPU加速,无头模式下不需要
    '--disable-service-worker', // 禁用Service Worker,减少后台持续请求
    '--blink-settings=imagesEnabled=false', // 禁用图片加载,进一步提速
    '--disable-ads' // 尝试内置的广告拦截(部分Chromium版本支持)
  ],
  headless: 'new', // 使用新版无头模式,稳定性更好
  defaultViewport: { width: 1280, height: 2000 }
});

4. 避免连续快速跳转,给页面留缓冲时间

不要一口气连续跳转多个页面,每次操作后给页面留一点稳定时间,比如加个短暂延迟或者等待domcontentloaded:

// 首页加载后,先等DOM加载完成再截图
await page.goto('https://www.discuss.com.hk');
await page.waitForNavigation({ waitUntil: 'domcontentloaded' });
await page.screenshot({ path: 'dis1.png' });

// 跳转前加1秒延迟,让当前页面状态稳定
await page.waitForTimeout(1000);
await page.goto('http://www.discuss.com.hk/forumdisplay.php?fid=215');
await page.waitForSelector('#threadlisttableid');
await page.screenshot({ path: 'dis2.png' });

你的原始代码:

async function run() { 
  const browser = await puppeteer.launch({ args: ['--no-sandbox', '--disable-setuid-sandbox'] }); 
  const page = await browser.newPage(); 
  page.setViewport({ width: 1280, height: 2000 }); 
  page.on('load', () => console.log('Page loaded!', page.url())); 
  //Goto website home page 
  await page.goto('https://www.discuss.com.hk'); 
  await page.screenshot({ path: 'dis1.png' }); 
  //goto another page in the website 
  await page.goto('http://www.discuss.com.hk/forumdisplay.php?fid=215'); 
  await page.screenshot({ path: 'dis2.png' }); 
  //Goto another page in the website 
  await page.goto('http://www.discuss.com.hk/forumdisplay.php?fid=1192'); 
  await page.screenshot({ path: 'dis3.png' }); 
  //Goto another page in the website 
  await page.goto('http://www.discuss.com.hk/viewthread.php?tid=27173245&extra=page%3D1'); 
  await page.screenshot({ path: 'dis4.png' }); 
  await browser.close(); 
  return 'done!'; 
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:06:01