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
相关产品推荐
相关产品推荐

