本项目github地址:https://github.com/janyin/dou...
若是须要,能够clone到本地css
$ npm install --save
$ node app
打开http://localhost:3030/index.html 可直接查看爬虫数据html
爬取斗鱼正在直播的主播数据(房间号,在线人数,房间标题,主播名称,直播分类等等)前端
安装npm包express+superagent+cheerionode
$ npm install express superagent cheerio --save
const express = require('express'); const superagent = require('superagent'); const cheerio = require('cheerio'); const app = express();
const url = 'https://www.douyu.com/directory/all'; const rooturl = 'https://www.douyu.com';
rooturl是斗鱼首页,url是斗鱼所有直播间第一页,rooturl后面直播间地址数据要用到jquery
在li里寻找到咱们须要的数据,最后push到data里git
app.get('/', function (req, response) { // 声明get请求在指定的路径下调用相应的回调函数 let data = [];//存放获取的数据 superagent.get(url).end(function (err, res) {//发起get请求 if (err) { console.log(err); } else { console.log('状态码:' + res.status); let $ = cheerio.load(res.text);//使用cheerio解析数据 $('#live-list-contentbox li').each(function (i, ele) { //获取目标数据 并遍历存放到data中 let href = rooturl + $(ele).find('a.play-list-link').attr('href');//href是存放的直播间id,加rooturl生成直播间连接 let lives = { name: $(ele).find('span.dy-name').text(), num: $(ele).find('span.dy-num').text(), title: $(ele).find('.mes-tit>h3').text().trim(), links: href,//直播间连接 }; data.push(lives); }) } response.send(data);//目标数据发送给前端
})github
app.listen(3030, function () { console.log('server is listening port 3030....'); })
最后node这个项目,打开http://localhost:3000/ 获得咱们须要的数据ajax
$ npm install async --save
100个页面能够先获取100个相应的url,可是发现斗鱼切换到第二页的时候其url并无改变,
经过chrome devtools发如今切换页面时的ajax请求。
发现ajax请求的url是https://www.douyu.com/gapi/rk... ,后面加的/2就是相应的页数(这里是第二页)chrome
const express = require('express'); const superagent = require('superagent'); const async = require('async'); const app = express(); const rooturl = 'https://www.douyu.com/gapi/rkc/directory/0_0';
function geturls(num) { let href = []; let urls = []; for (let i = 1; i <= num; i++) { href.push('/' + i); } href.forEach(function (ele) { urls.push(rooturl + ele); }) return urls; }
传进去的num是多少,返回的url就有多少express
app.get('/data', function (req, res) { let urls = geturls(100); //获取100个url let datas = []; //存放目标数据 async.mapLimit(urls,25,function (url, callback) { //异步发送请求 fetchPage(url, callback);//分析数据并提取 }, function (err, result) { console.log('分析完成!'); res.send(datas);//发送数据给前端 }); })
async.mapLimit(coll, limit, iteratee, callback)
ps:最后一个函数里result参数的数据和datas数组数据是同样的,发送datas主要是方便后面页面提取
function fetchPage(url, callback) { superagent.get(url).end(function (err, sres) { if (err) { console.log(err); } else { let item = JSON.parse(sres.text);//解析json数据 let list = item.data.rl; list.forEach(function (ele) {//提取须要的数据 let obj = { name: ele.nn, id: ele.rid, online: ele.ol, title: ele.rn, class: ele.c2name, }; datas.push(obj); }); callback(null, datas);//这个datas会发送给result } }) } })
由于ajax请求直接返回的是json数据就不须要上面的cheerio解析
app.use(express.static('public')) app.listen(3030, function () { console.log('server is listening port 3030....'); })
以上代码均在app.js里