求助:Async函数抛出未捕获错误,Node.js爬虫Promise拒绝问题
解决你的Node.js Puppeteer爬虫错误问题
嘿,我来帮你搞定这个爬虫的问题!你遇到的错误其实是两个关联的核心问题:DOM元素找不到导致的null引用错误,以及未处理的Promise拒绝,我一步步给你讲怎么修复:
问题1:Cannot read property 'innerText' of null
这个错误说明你用document.querySelector查找元素时,页面上根本不存在匹配的元素,大概率是这几个原因:
- 页面还没完全加载完成,你就急于获取元素
- CSS选择器写得不准确,匹配不到任何元素
- 目标元素是通过JavaScript动态渲染的,需要等待它加载出现
解决办法:
- 用
page.waitForSelector()先等待目标元素加载完成,再去读取内容 - 在
page.evaluate里先判断元素是否存在,再访问innerText,避免直接调用导致报错
问题2:未处理的Promise拒绝
你整个异步自执行函数里没有错误捕获逻辑,一旦任何await的Promise失败(比如页面加载失败、元素找不到),就会抛出未处理的Promise拒绝错误。解决办法是给异步代码加上try/catch块,或者在函数末尾加.catch()兜底。
修改后的完整代码
const puppeteer = require('puppeteer'); const fs = require('fs'); (async () => { let browser; try { browser = await puppeteer.launch(); const page = await browser.newPage(); const opportunity = { title: '', desc: '', category: '', reqName: '', hours: '', postingDate: '', address: '' }; // 等待页面完全加载(包括动态内容) await page.goto('https://recruiting2.ultipro.com/PUB1004PSCU/JobBoard/d433f5c3-37c8-4bcf-a3af-248a707c7d31/?q=&o=postedDateDesc', { waitUntil: 'networkidle2' // 等待网络空闲,确保动态资源加载完毕 }); // 先等待标题元素出现,再获取内容 await page.waitForSelector('.opportunity .row .col-lg-20 h3 a'); const title = await page.evaluate(() => { const element = document.querySelector('.opportunity .row .col-lg-20 h3 a'); // 元素存在才返回innerText,否则返回自定义提示 return element ? element.innerText : '标题未找到'; }); // 同样处理描述元素 await page.waitForSelector('.opportunity .hidden-xs.paragraph'); const desc = await page.evaluate(() => { const element = document.querySelector('.opportunity .hidden-xs.paragraph'); return element ? element.innerText : '描述未找到'; }); opportunity.title = title; opportunity.desc = desc; console.log(opportunity); } catch (error) { // 捕获所有错误并打印,方便调试 console.error('爬虫运行出错:', error); } finally { // 不管成功失败,都确保浏览器关闭,避免内存泄漏 if (browser) { await browser.close(); } } })().catch(err => console.error('全局错误捕获:', err)); // 全局兜底捕获,双重保障
关键修改点说明
- 把
browser变量提到外部,确保在finally块里能访问到,保证浏览器一定会关闭 - 给
page.goto加上waitUntil: 'networkidle2',等待页面动态内容加载完成 - 用
page.waitForSelector()等待目标元素出现,避免元素还没渲染就去获取 - 在
page.evaluate里先判断元素是否存在,再访问innerText,防止null报错 - 整个逻辑包裹在
try/catch里,捕获所有异步错误 - 用
finally块确保浏览器关闭,避免资源泄漏 - 在自执行函数末尾加
.catch(),作为全局错误捕获的最后一道防线
这样修改后,你的爬虫就不会再随机抛出未处理的Promise拒绝错误,同时也能优雅处理元素找不到的情况啦!
内容的提问来源于stack exchange,提问作者Charles L.
相关产品推荐
相关产品推荐

