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

【爬虫】nodejs爬取斗鱼直播间数据实战

时间:2023-04-04 00:29:36 Node.js

前提本项目github地址:https://github.com/janyin/dou...如果需要可以clone到本地$npminstall--save$nodeapp打开http://localhost:3030/index.html可以直接查看爬虫数据。目标爬取斗鱼直播主播数据(房间号、在线号、房间标题、主播姓名、直播分类等)依赖构建安装npm包express+superagent+cheerio$npminstallexpresssuperagentcheerio--saveexpress:Node.jsweb应用框架superagent:一个小型的渐进式客户端HTTP请求库,与Node.js模块具有相同的API,具有很多高级的HTTP客户端功能cheerio:可以理解为Node.js版本的jquery,它用于使用css选择器从网页中获取数据。使用方法与jquery基本相同。Step1.引入依赖并实例化expressconstexpress=require('express');constsuperagent=require('superagent');constcheerio=require('cheerio');constapp=express();2.定义目标urlconsturl='https://www.douyu.com/directory/all';constrooturl='https://www.douyu.com';rooturl为斗鱼首页,url为所有斗鱼直播间的首页,使用rooturl后面的直播间地址数据3.发送请求获取数据分析数据生成页面数据发送给前端withsuperagent向斗鱼发送get请求,回调函数接收到的数据由cheerio解析,从而可以用jqueryselector进行操作。使用cheerio.load()分析打开斗鱼,发现其直播列表在id中的live-list-contentbox的ul中,使用jquery选择器获取所有的li,遍历找到我们需要的数据在里,最后推送到数据app.get('/',function(req,response){//声明get请求在指定路径下调用对应的回调函数letdata=[];//存储获取到的数据superagent.get(url).end(function(err,res){//发起get请求if(err){console.log(err);}else{console.log('statuscode:'+res.status);let$=cheerio.load(res.text);//使用cheerio来parsedata$('#live-list-contentboxli').each(function(i,ele){//获取目标数据存入datalethref=rooturl+$(ele).find('a.play-list-link').attr('href');//href为存储的直播间id,添加rooturl生成直播间链接letlives={name:$(ele).find('span.dy-名称').text(),num:$(ele).find('span.dy-num').text(),title:$(ele).find('.mes-tit>h3').text().trim(),links:href,//直播间链接};data.push(lives);})}response.send(data);//目标数据发送给前端})4.监听portapp.listen(3030,function(){console.log('serverislisteningport3030....');})最后,对于node项目,打开http://localhost:3000/获取我们需要的数据以上所有代码都在first.js中。爬虫数据部分结果:高级爬虫思维:这只是斗鱼首页主播的数据。100页数据或全部数据呢?这个时候就需要async了。不可能同步发送100个请求。很容易被误认为是恶意攻击。Async提供了一个直接而强大的函数来处理异步JavaScript。虽然它最初是为Node.js设计的,但也可以直接在浏览器中使用。使用$npminstallasync--save分析100个页面,可以先得到100个对应的url,但是发现斗鱼切换到第二个页面的时候url并没有变化。通过chromedevtools发现切换页面时的ajax询问发现ajax请求的url是https://www.douyu.com/gapi/rk...,后面加的/2就是对应的页码(这里是第二页),实现爬虫1、同上constexpress=require('express');constsuperagent=require('superagent');constasync=require('async');constapp=express();constrooturl='https://www.douyu.com/gapi/rkc/directory/0_0';2.声明一个函数来获取所有的urlfunctiongeturls(num){lethref=[];让urls=[];for(leti=1;i<=num;i++){href.push('/'+i);}href.forEach(function(ele){urls.push(rooturl+ele);})returnurls;}传入多少nums,返回多少url3.async异步发送请求app.get('/data',function(req,res){leturls=geturls(100);//获取100个urlletdatas=[];//存储目标数据async.mapLimit(urls,25,function(url,callback){//异步发送请求fetchPage(url,callback);//分析提取数据},function(err,result){console.log('分析完成!');res.send(datas);//发送数据到frontend});})async.mapLimit(coll,limit,iteratee,callback)coll是迭代的集合,是一个数组,用来存放urllimitonce函数申请到的最多需要发送的异步操作数每一个项目collcallback是可选的,当所有迭代函数完成或发生错误时调用的回调ps:最后一个函数中result参数的数据与datas数组的数据相同。发送datas主要是方便后续页面提取4.分析页面函数;}else{letitem=JSON.parse(sres.text);//解析json数据letlist=item.data.rl;list.forEach(function(ele){//提取需要的数据letobj={name:ele.nn,id:ele.rid,online:ele.ol,title:ele.rn,class:ele.c2name,};datas.push(obj);});callback(null,datas);//这个数据会被发送到result}})}})因为ajax请求直接返回json数据,所以不需要上面的cheerio解析5.设置静态文件目录app.use(express.static('public'))app.listen(3030,function(){console.log('serverislisteningport3030....');})6.编写前端html并显示数据前端代码在index.html在里面,主要目的是获取数据遍历并输出到表中,还有一个搜索功能(不建议搜索1W以上的数据,会很卡)以上代码都在app中。js