当前位置: 首页 > 后端技术 > Node.js

使用Promise实现队列(爬MOOCHTML代码)

时间:2023-04-04 01:13:23 Node.js

项目初始化创建package.json文件,webstorm快速创建package.json非常简单。使用npminit快速构建。工具模块需要下载模块superagentpagedata下载cheeriopagedataanalysis这是2个npm包,我们先下载:npminstallsuperagentcheerio--save需要导入的模块fspathimportprojectdependenciesconstcheerio=require('cheerio');constagent=require('superagent');constpath=require('path');constfs=require('fs');定义地址数组我们要以队列的形式逐一访问这些地址得到html代码,用于后续处理:consturls=[{page:1,url:"https://www.imooc.com/course/list?c=fe&page=1"},{page:2,url:"https://www.imooc.com/course/list?c=fe&page=2"},{page:3,url:"https://www.imooc.com/course/list?c=fe&page=3"}];定义数据结构MOOC课程列表:为此,我们定义以下数据结构:[{page:1,data:[{title:"",//课程标题imgurl:"",//课程图片级别:"",//Levelstudynum:0,//学生人数description:"xxxx"//课程描述}......//每页有多个课程信息]}......//一共有[多个页面]superagent页面数据下载superagent是nodejs中一个非常方便的客户端请求代码模块,superagent是一个轻量级、渐进式ajaxAPI,可读性好,学习曲线低,内部依赖nodejs原生RequestAPI,适用于nodejs环境。基本使用方法:请点击链接查看详情...request.get('/login').end(function(err,res){//code});cheerio页面数据分析cheerio是一个node库,可以理解为node.js版本的jquery,用于通过css选择器从网页中抓取数据,用法与jquery基本相同。需要先加载一个html文档,然后就可以像jQuery一样使用操作页面了。基本使用方法:请点击链接查看详情...constcheerio=require('cheerio');const$=cheerio.load('...');$('#fruits').addClass('newClass');使用Promise实现队列是本文的重头戏。。。需要用到数组reduce()arr.reduce([callback,initialValue])的一个方法不明白这个方法的可以查看我的笔记:https://segmentfault.com/n/13...reduce()方法接收一个函数作为累加器,数组中的每个值(从左到右)开始收缩并以一个值结束。callback(执行数组中每个值的函数,包括四个参数)initialValue(作为第一次调用callback的第一个参数。)还有一个实现异步处理的Promise。如果你不知道这个方法,你可以检查一下。备注:https://segmentfault.com/n/13...具体使用Promise的这个方法:Promise.resolve()这个方法返回一个fulfilled的Promise实例,或者是原始的Promise实例。代码实现://实现队列//本质:累加.then()方法letcurPromise=urls.reduce((promise,curl)=>{returnpromise.then(()=>{returnnewPromise(resolve=>{//网络获取当前地址的网页内容requestGet(curl,()=>{resolve();});});});},Promise.resolve());将数据写入result.json文件中间代码实现://写入数据curPromise.then(()=>{fs.writeFile('result.json',JSON.stringify(result),function(err){if(err)thrownewError("appendFilefailed...");console.log("数据写入成功...");});});完整代码//项目依赖constcheerio=require('cheerio');constagent=require('superagent');constpath=require('path');constfs=require('fs');//地址数据consturls=[{page:1,url:"https://www.imooc.com/course/list?c=fe&page=1"},{page:2,url:"https://www.imooc.com/course/list?c=fe&page=2"},{page:3,url:"https://www.imooc.com/course/list?c=fe&page=3"}];//最终数据letresult=[];//数据结构/***[*{*page:1,*data:[*{title:xx,imgurl:xx...},*...*]*}*...*]*///启动获取请求函数requestGet(urlObj,callback){agent.get(urlObj.url).end((err,res)=>{if(err)thrownewError(err);//分析页面letpageJson=analysis(res.text);//拼接数据result.push({page:urlObj.page,data:pageJson});console.log(`将数据写入页面${urlObj.page}...`);//执行回调callback();});}//分析网页函数analysis(data){letpage=[];让$=cheerio.load(数据);让courseArr=$(".course-list").find(".course-card-container");courseArr.each((index,element)=>{let_this=$(element);//组装数据page.push({title:_this.find(".course-card-name").text(),imgurl:path.join("http:",_this.find(".course-card-topimg").attr("src")),level:_this.find(".course-card-infospan:first-child").text(),//level:_this.find(".icon-set_sns").parent().prev().text(),studynum:_this.find(".icon-set_sns").parent().text(),description:_this.find(".course-card-desc").text()});});returnpage;}//实现队列//本质:累加.then()方法letcurPromise=urls.reduce((promise,curl)=>{returnpromise.then(()=>{returnnewPromise(resolve=>{//具体内容requestGet(curl,()=>{resolve();});});});},Promise.resolve());//写入数据curPromise.then(()=>{fs.writeFile('result.json',JSON.stringify(result),function(err){if(err)thrownewError("appendFilefailed...");console.log("数据写入回车成功。..");});});启动项目nodeapp.js,可以看到终端有序的输出了如下内容:打开生成的result.json文件,其结构也符合我们的预期:至此,本文结束。如果您有好的想法,请留言。继续学习...