Node爬取拉勾网的数据并导出为ex??cel文件Node算是新手了,希望和大家一起学习进步。1.概述我们首先要明确具体的需求:我们可以通过nodeindexcitypositions来爬取相关信息,或者进入nodeindexstart直接爬取我们预定义的city和position数组,循环爬取不同城市的不同职位信息存储起来最终爬取的结果在本地./data目录下生成对应的excel文件存储在本地2.爬虫使用的相关模块fs:用于读写系统文件和目录async:进程控制superagent:客户端请求代理模块node-xlsx:导出一定格式的文件到excel3.爬虫主要步骤:初始化项目,新建项目目录,在合适的磁盘目录下创建项目目录node-crwl-lagou,初始化项目,进入node-crwl在-lagou文件夹下执行npminit,初始化package.json文件,安装依赖包它,它会返回一个数组,数组的每一项都是用户输入的内容。要区分节点索引地理位置和节点索引开始这两个输入,最简单的方法就是判断process.argv的长度。如果长度为四,我们就直接调用爬虫主程序来爬取数据。如果长度为三,我们需要通过预定义的city和position数组来拼接url,然后使用async.mapSeries循环调用主程序。命令分析的首页代码如下:if(process.argv.length===4){letargs=process.argvconsole.log('准备开始请求'+args[2]+'of'+args[3]+'工作数据');requsetCrwl.controlRequest(args[2],args[3])}elseif(process.argv.length===3&&process.argv[2]==='start'){letarr=[]for(leti=0;i{superagent.post(`https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false&city=${city}&kd=${position}&pn=1`).send({'pn':1,'kd':position,'first':true}).set(options.options).end((err,res)=>{if(err)throwerr//console.log(res.text)letresObj=JSON.parse(res.text)if(resObj.success===true){totalPage=resObj.content.positionResult.totalCount;cb(null,totalPage);}else{console.log(`failedtogetdata:${res.text}}`)}})},得到总页数后,我们可以得到pn参数按总页数/15,循环生成所有url存入urls:(cb)=>{for(leti=0;Math.ceil(i{async.mapLimit(urls,3,(url,callback)=>{num++;letpage=url.split('&')[3].split('=')[1];superagent.post(url).send({'pn':totalPage,'kd':position,'first':false}).set(options.options).end((err,res)=>{if(err)throwerrletresObj=JSON.parse(res.text)if(resObj.success===true){console.log(`Crawlingpage${page},currentconcurrentnumber:${num}`);if(!fs.existsSync('./data')){fs.mkdirSync('./data');}//以.json格式存储数据到dat中fs.writeFile(`./data/${city}_${position}_${page}.json`,res.text,(err)=>{if(err)throwerr;//写入数据后,两秒后发送下一个请求setTimeout(()=>{num--;console.log(`Thepage${page}wassuccessfulwritten`);callback(null,'success');},2000);});}})},(err,result)=>{if(err)抛出错误;//这个arguments是调用controlRequest函数的参数,可以区分爬取的种类(循环还是单次)if(arguments[2]){ok=1;}cb(null,ok)})},()=>{if(ok){setTimeout(function(){console.log(`${city}${position}数据请求完成`);indexCallback(null);},5000);}else{console.log(`${city}${position}数据请求完成`);}//exportExcel.exportExcel()//导出到excel}导出的json文件如下:json文件导出到exceljson文件导出到excel的方法有很多种。我用的是node包node-xlsx,需要把数据格式化成固定的格式传入再导出,所以我们首先要做的就是拼出需要的数据格式:functionexportExcel(){letlist=fs.readdirSync('./data')letdataArr=[]list.forEach((item,index)=>{letpath=`./data/${item}`letobj=fs.readFileSync(path,'utf-8')letcontent=JSON.parse(obj).content.positionResult.resultletarr=[['companyFullName','createTime','workYear','education','city','positionName','positionAdvantage','companyLabelList','salary']]content.forEach((contentItem)=>{arr.push([contentItem.companyFullName,contentItem.phone,contentItem.workYear,contentItem.education,contentItem.city,contentItem.positionName,contentItem.positionAdvantage,contentItem.companyLabelList.join(','),contentItem薪水])})dataArr[index]={data:arr,name:path.split('./data/')[1]//name不能包含\/?*[]}})//数据格式//vardata=[//{//名称:'sheet1',//数据:[//[//'ID',//'名称',//'分数'//],//[//'1',//'迈克尔',//'99'////],//[//'2',//'乔丹',//'98'//]//]//},//{//名称:'sheet2',//数据:[//[//'AA',//'BB'//],//[//'23',//'24'//]//]//}//]//写入xlsxvarbuffer=xlsx.build(dataArr)fs.writeFile('./result.xlsx',buffer,function(err){if(err)throwerr;console.log('Writetoxlshasfinished');//读取xlsx//varobj=xlsx.parse("./"+"resut.xls");//console.log(JSON.stringify(obj));});}导出的excel文件如下。每个页面的数据是一个sheet,比较清晰:我们可以从中清楚的看到西安网目前的招聘情况,然后也可以考虑把爬取到的数据以更加图形化的方式展现出来,应该是更直观!综上所述,整个爬取过程并不复杂。注意还有很多小点需要注意,比如async和exportsettingheaders的各种方法的使用。总之,也是收获满满!源码gitbug地址:https://github.com/fighting12...