Puppeteer异步函数返回值赋值失败,打印结果为undefined
问题原因
你遇到的核心问题是async函数的返回值是Promise对象,不是你直接return的包含breakfast、lunch的菜单对象。所以const menu = getMenu()得到的是一个Promise实例,而非预期的菜单数据,自然menu.breakfast会显示undefined。
解决方法
有两种简单的方式可以获取到正确的菜单对象:
方法一:用async/await包裹调用逻辑
await只能在async函数内部使用,所以可以把调用代码放到一个async函数里:
const puppeteer = require("puppeteer"); async function getMenu() { console.log("Opening the browser..."); const browser = await puppeteer.launch({ headless: true }); const page = await browser.newPage(); await page.goto('https://pra.ufpr.br/ru/ru-centro-politecnico/', {waitUntil: 'domcontentloaded'}); console.log("Content loaded..."); const fullMenu = await page.evaluate(() => { return { day: document.querySelector('#conteudo div:nth-child(3) p strong').innerText, breakfastFood: document.querySelector('tbody tr:nth-child(2)').innerText, lunchFood: document.querySelector('tbody tr:nth-child(4)').innerText, dinnerFood: document.querySelector('tbody tr:nth-child(6)').innerText }; }); await browser.close(); return { breakfast: fullMenu.day + "\nCafé da Manhã:\n" + fullMenu.breakfastFood, lunch: fullMenu.day + "\nAlmoço:\n" + fullMenu.lunchFood, dinner: fullMenu.day + "\nJantar:\n" + fullMenu.dinnerFood }; }; // 用async函数包裹调用 async function main() { const menu = await getMenu(); console.log(menu.breakfast); } main();
方法二:用Promise的.then()处理返回值
如果不想额外写async函数,直接用Promise的then方法读取结果:
const puppeteer = require("puppeteer"); async function getMenu() { // 原函数内容保持不变 }; getMenu().then(menu => { console.log(menu.breakfast); });
额外优化建议
可以给爬虫加个错误处理,避免页面元素找不到时程序崩溃,比如在page.evaluate里做元素判空,或者给整个getMenu函数加try/catch:
async function getMenu() { try { console.log("Opening the browser..."); const browser = await puppeteer.launch({ headless: true }); const page = await browser.newPage(); await page.goto('https://pra.ufpr.br/ru/ru-centro-politecnico/', {waitUntil: 'domcontentloaded'}); console.log("Content loaded..."); const fullMenu = await page.evaluate(() => { const dayEl = document.querySelector('#conteudo div:nth-child(3) p strong'); const breakfastEl = document.querySelector('tbody tr:nth-child(2)'); const lunchEl = document.querySelector('tbody tr:nth-child(4)'); const dinnerEl = document.querySelector('tbody tr:nth-child(6)'); return { day: dayEl ? dayEl.innerText : '未获取到日期', breakfastFood: breakfastEl ? breakfastEl.innerText : '未获取到早餐', lunchFood: lunchEl ? lunchEl.innerText : '未获取到午餐', dinnerFood: dinnerEl ? dinnerEl.innerText : '未获取到晚餐' }; }); await browser.close(); return { breakfast: fullMenu.day + "\nCafé da Manhã:\n" + fullMenu.breakfastFood, lunch: fullMenu.day + "\nAlmoço:\n" + fullMenu.lunchFood, dinner: fullMenu.day + "\nJantar:\n" + fullMenu.dinnerFood }; } catch (error) { console.error('获取菜单出错:', error); return { breakfast: '获取失败', lunch: '获取失败', dinner: '获取失败' }; } };
内容的提问来源于stack exchange,提问作者João
相关产品推荐
相关产品推荐

