Puppeteer调用browser.close()无法自动关闭浏览器问题求助
问题根源
- 递归函数
getData多处等待操作设置了timeout: 0,一旦某一页加载异常、谷歌触发人机验证、或者分页到最后没有匹配的yuRUbf选择器时,函数会进入无限等待状态,永远不会返回结果,后续的browser.close()和打印逻辑根本不会执行。你手动关闭浏览器后,所有页面操作会抛出连接中断错误,递归链路才会终止,因此只有手动关浏览器后才会输出爬取数据。 - 你使用的谷歌搜索URL携带了固定的临时会话参数(sxsrf、ei等),这些参数有有效期,翻页到一定次数后会失效,导致返回的页面结构和预期不符,触发
waitForSelector无限等待。 - 错误捕获分支没有返回值,一旦某层递归触发异常,会导致递归链路断裂卡住,无法正常返回结果。
修复方案
- 给所有等待操作设置合理的超时时间,避免无限等待
- 错误捕获分支明确返回空数组,保证递归链路始终可以正常结束
- 改用不带临时会话参数的通用谷歌搜索URL,避免参数过期问题
- 增加分页深度限制,避免无意义的无限递归
修复后代码
const puppeteer = require("puppeteer"); (async () => { const getData = async (url, start = 0) => { // 增加最大分页限制,最多爬10页,可按需调整 if (start > 100) return [] try { const page = await browser.newPage(); await page.setViewport({ width: 1366, height: 768 }); const query = `${url}&start=${start}`; // 超时时间设为30秒,可按需调整 await page.goto(query, { waitUntil: "load", timeout: 30000 }); await page.waitForSelector('div[class="yuRUbf"] > a', { timeout: 30000 }); const links = await page.evaluate(() => Array.from(document.querySelectorAll('div[class="yuRUbf"] > a')).map( (a) => a.href ) ); await page.close(); if (links.length < 1) { return links; } else { return links.concat(await getData(url, start + 10)); } } catch (error) { console.log("爬取异常:", error); // 异常分支返回空数组,保证递归逻辑正常结束 return [] } }; const browser = await puppeteer.launch({ headless: false }); // 移除临时会话参数,使用通用搜索URL const url = "https://www.google.com/search?q=Let+You+Love+Me+by+Rita+Ora"; const allLinks = await getData(url); await browser.close(); console.log("爬取到的所有链接:", allLinks); })();
内容的提问来源于stack exchange,提问作者Ali Raza
相关产品推荐
相关产品推荐

