Node.js Puppeteer商品爬虫触发DEP0018未处理Promise拒绝警告
运行Node.js爬取脚本触发 DEP0018 弃用警告
问题背景
- 学习Node.js网页爬取技术时,跟随对应教程完成基础示例开发,原有示例代码可正常运行
- 自主实现ASDA超市可口可乐商品页面图片爬取功能时,脚本运行异常,控制台抛出警告信息:
(node:93364) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated - 目前无法定位异常根因,编写的完整爬取代码如下:
const puppeteer = require('puppeteer') async function scrapeProduct(url){ const browser = await puppeteer.launch() const page = await browser.newPage() await page.goto(url) const [el] = await page.$x('//*[@id="s7viewer_swatches_listbox"]/div[1]/div/div') const src = await el.getProperty('src') const image = await src.jsonValue() console.log({image}) browser.close() } scrapeProduct('https://groceries.asda.com/product/regular-cola/coca-cola-classic-bottle/1000020585281')
根因分析与修复方案
- 触发该警告的核心原因是代码中存在未被捕获的Promise异常:所有异步操作抛出的错误没有被捕获处理,新版本Node.js中这类未处理的Promise rejection会直接标记为弃用行为
- 代码中的具体异常触发点:
- 原XPath选择器路径指向div容器,不是实际带
src属性的img标签,导致page.$x()匹配失败,返回空数组后解构得到的el为undefined,后续调用el.getProperty()会直接抛出类型错误 - 所有异步流程(浏览器启动、页面跳转、元素查询)抛出的异常没有被捕获,最外层调用
scrapeProduct()时没有设置Promise错误兜底 - 未处理SPA页面的元素渲染等待逻辑,页面DOM未完全加载就执行元素查询,会进一步提升匹配失败的概率
- 原XPath选择器路径指向div容器,不是实际带
- 修复后的参考实现:
const puppeteer = require('puppeteer') async function scrapeProduct(url){ let browser try { browser = await puppeteer.launch({ headless: 'new' }) const page = await browser.newPage() // 配置页面加载等待规则,确保DOM渲染完成 await page.goto(url, { waitUntil: 'networkidle2' }) // 修正XPath匹配实际带src的图片标签 const [el] = await page.$x('//*[@id="s7viewer_swatches_listbox"]/div[1]/div/div//img') if (!el) throw new Error('目标图片元素未匹配,请检查XPath规则') const src = await el.getProperty('src') const image = await src.jsonValue() console.log({image}) } catch (err) { // 捕获全流程异步异常,避免未处理的Promise rejection console.error('爬取流程异常:', err.message) } finally { // 无论流程是否出错,都释放浏览器资源 if (browser) await browser.close() } } scrapeProduct('https://groceries.asda.com/product/regular-cola/coca-cola-classic-bottle/1000020585281')
- 日常开发注意点:
- 所有异步函数内的操作都需要通过
try/catch块捕获异常 - 最外层直接调用异步函数时,需要通过
.catch()添加兜底逻辑,避免触发未处理的Promise弃用警告 - 编写XPath规则时,需要匹配实际带目标属性(如
src)的元素节点,不要选择父级容器
- 所有异步函数内的操作都需要通过
内容的提问来源于stack exchange,提问作者hbk1414
相关产品推荐
相关产品推荐

