Node.js中使用Cheerio爬取数据无法返回至变量,请求技术帮助
解决异步爬取数据无法返回至变量的问题
看起来你碰到了Node.js异步编程的经典坑——request是基于回调的异步方法,直接在parse函数里return肯定拿不到数据,因为代码执行到return时,HTTP请求还在后台跑呢!控制台能打印是因为回调函数里的代码是请求完成后才执行的,那时候数据已经拿到了。
我来帮你改造代码,让爬取到的数据能正常返回给变量:
改造方案:用Promise包装异步操作
把MealParser.parse改成返回Promise的函数,这样就能用async/await或者.then()来获取结果了:
const cheerio = require("cheerio"); const request = require("request"); const init_url = "https://stu.dje.go.kr/sts_sci_md01_001.do?schulCode=G100000208&schulCrseScCode=4&schulKndScCode=04&schMmealScCode=2"; const MealParser = {}; MealParser.parse = () => { // 返回一个Promise对象,用于处理异步逻辑 return new Promise((resolve, reject) => { request(init_url, (error, response, body) => { // 处理请求错误 if (error) { reject(error); return; } // 检查响应状态码是否正常 if (response.statusCode !== 200) { reject(new Error(`请求失败,状态码:${response.statusCode}`)); return; } // 用Cheerio解析HTML内容 const $ = cheerio.load(body); // 这里替换成你实际要提取的逻辑,比如提取餐食信息 const mealInfo = []; $(".tbl_type3 tbody td").each((_, el) => { const text = $(el).text().trim(); if (text && text !== "-") { mealInfo.push(text); } }); // 把解析好的数据传递出去 resolve(mealInfo); }); }); }; // 在聊天机器人逻辑中这样调用 async function getMealForBot() { try { // 用await等待Promise完成,拿到最终数据 const mealData = await MealParser.parse(); console.log("爬取到的餐食数据:", mealData); // 这里就可以把mealData返回给聊天机器人的消息发送逻辑了 return mealData; } catch (err) { console.error("爬取解析出错:", err); // 可以在这里返回错误提示给用户 return "暂时无法获取餐食信息哦"; } } // 测试调用 getMealForBot();
为什么原来的代码拿不到返回值?
原来的parse函数里,request是异步执行的——函数会先执行request(...)发起请求,但不会等待请求完成就直接执行后续的return,此时请求还没拿到数据,自然返回空值或者undefined。而控制台能打印是因为回调函数(error, response, body) => {...}是在请求成功拿到响应后才触发的,这时候数据已经存在了。
额外小建议
如果你不想手动包装Promise,可以直接用request-promise模块(它是request的Promise化封装),安装后直接用async/await写法,代码会更简洁:
npm install request-promise
const cheerio = require("cheerio"); const rp = require("request-promise"); MealParser.parse = async () => { const body = await rp(init_url); const $ = cheerio.load(body); // 后续解析逻辑和之前一致 const mealInfo = []; $(".tbl_type3 tbody td").each((_, el) => { const text = $(el).text().trim(); if (text && text !== "-") { mealInfo.push(text); } }); return mealInfo; };
这样改造后,你就能正常把爬取到的数据返回给变量,再传递给聊天机器人的用户啦!
内容的提问来源于stack exchange,提问作者지영채
相关产品推荐
相关产品推荐

