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

Puppeteer中waitForSelector无法找到元素,加载错误原因排查

Puppeteer检测页面元素加载失败的问题分析与修复

问题根源分析

你的代码存在几个关键问题导致始终返回加载错误:

  • 循环内提前关闭页面:第一次循环的.then()中调用了await page.close(),后续循环再使用这个已关闭的page对象必然失败,直接触发catch逻辑。
  • 无头浏览器被反爬拦截:Investing.com会检测无头模式的浏览器特征,导致目标元素无法正常渲染加载。
  • 错误处理过于笼统:仅输出"Loading error",无法定位具体是超时、元素不存在还是页面异常。
  • 缺少必要的浏览器配置:无头模式下默认的User-Agent可能被识别,需要手动设置正常的浏览器标识。

修复后的代码

async function getResults(lnk) {
  const results = [];
  const timeFrames = [1, 5, 15];

  const browser = await puppeteer.launch({
    headless: "new", // 使用新版无头模式,更接近真实浏览器
    args: [
      "--no-sandbox",
      "--disable-setuid-sandbox",
      "--disable-dev-shm-usage",
      // 移除易被反爬识别的参数
      "--start-maximized"
    ],
    timeout: 0,
    executablePath:
      process.env.NODE_ENV === "production"
        ? process.env.PUPPETEER_EXECUTABLE_PATH
        : puppeteer.executablePath(),
  });

  for (const i of timeFrames) {
    const url = `${lnk}?timeFrame=${i * 60}`;
    console.log(`Getting: ${url}`);

    // 每次循环新建页面,避免复用已关闭页面
    const page = await browser.newPage();
    
    // 设置真实浏览器的User-Agent,规避反爬检测
    await page.setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36");

    try {
      // 延长页面加载超时时间,等待网络请求稳定
      await page.goto(url, { waitUntil: "networkidle2", timeout: 60000 });
      
      console.log("Process 1");

      // 明确设置元素等待超时,确保有足够时间渲染
      await page.waitForSelector("section.forecast-box-graph", { timeout: 30000 });
      
      console.log("获取元素内容");

      const status = await page.$eval(
        "section.forecast-box-graph .title",
        el => el.textContent.trim()
      );
      const Bank_Name = await page.$eval(
        "h1.main-title.js-main-title",
        el => el.textContent.trim()
      );
      
      results.push({ timeFrame: i, status, Bank_Name });
      
    } catch (error) {
      // 打印具体错误信息,便于精准排查
      console.log(`加载失败(timeFrame=${i}):`, error.message);
      results.push({ timeFrame: i, error: error.message });
    } finally {
      // 无论成功失败,关闭当前页面释放资源
      await page.close();
    }
  }

  await browser.close();

  // 添加银行名称到结果
  results.push(lnk.split("/").pop().split("-").join(" "));

  return results;
}

额外优化建议

  • 处理Cookie弹窗:目标页面可能存在Cookie同意弹窗,可添加逻辑关闭,避免影响元素定位:
    await page.waitForSelector(".onetrust-close-btn-handler", { timeout: 10000 })
      .then(el => el.click())
      .catch(() => console.log("无Cookie弹窗"));
    
  • 增加重试机制:针对偶尔加载失败的情况,对单个URL添加重试逻辑,提升整体稳定性。
  • 等待元素文本加载:若需确保内容完全渲染,可使用page.waitForFunction()等待元素文本非空:
    await page.waitForFunction(() => document.querySelector("section.forecast-box-graph .title")?.textContent.trim() !== "", { timeout: 20000 });
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 11:47:44