展示

代码

const http = require('http'),
    url = require('url'),
    superagent = require('superagent'),
    cheerio = require('cheerio'),
    async = require('async'),
    eventproxy = require('eventproxy'),
     fs = require('fs');  


let ep = new eventproxy(),
    pagenum = 90,
    pageContent = [],
    pageUrls = [],
    allNumber = 0,
    targetUrl = "https://www.douyu.com/directory/all";

for (let i = 1; i <= pagenum; i++){
    pageUrls.push(`${targetUrl}?page=${i}&isAjax=1`)
}

//初始化总页




    function onRequest(req, res) {
        //循环请求所有页面
        pageUrls.forEach((url) => {
            superagent.get(url)
                .end((err, pres) => {
                    let $ = cheerio.load(pres.text)
                    let curPageUrl = $('li > a')
                    
                    //单个主播房间的信息进行遍历
                    for (let i = 0; i < curPageUrl.length; i++){
                        let curlRoom = curPageUrl.eq(i)
                        let curlRoomNumber = curlRoom.attr("data-rid")
                        let curlRoomWatcher = curlRoom.find(".dy-num").text()
                        let curlRoomName = curlRoom.find(".dy-name").text()

                        pageContent.push({
                            name: curlRoomName,
                            room: curlRoomNumber,
                            number:parseNumber(curlRoomWatcher)
                        })


                        allNumber += parseNumber(curlRoomWatcher)
                        ep.emit("comRead")
                    }
            })
        })
}
    

    
    ep.after('comRead', pagenum * 120, function (tpl, data) {
        let stringPageContent = JSON.stringify(pageContent);
        fs.writeFile('douyu.json', stringPageContent, function (err) {
            if (err) {
                console.log(err + " 发生错误");
            }
            console.log("\x1b[34m","创建Json数据成功" + new Date());
        })
        console.log("\x1b[31m", '统计完成!');
        console.log("\x1b[32m", '总人数为:', allNumber);
        console.log("\x1b[33m","共统计了",pageContent.length,"个主播");
    });
    //所有统计完成之后 输出总人数

    onRequest();

    


//util

function parseNumber(StringNumber) {
        let res;
        let arrayNumber = StringNumber.split('')
        if (arrayNumber[arrayNumber.length - 1] === "万") {
            arrayNumber.pop()
            arrayNumber.removeByValue(".")
            arrayNumber = arrayNumber.concat([0,0,0])
        }
        res = parseInt(arrayNumber.join(""))
            return res
    }
         


Array.prototype.removeByValue = function (val) {
  for(var i=0; i<this.length; i++) {
    if(this[i] == val) {
      this.splice(i, 1);
      break;
    }
  }
}

代码其实非常简单,爬虫最重要的就是对于一个网站的分析解构。

斗鱼的所有主播列表都在 https://www.douyu.com/directory/all 这个地址下,而他获取列表的方式是发送一个ajax的get请求,其参数有pages 和 isAjax两项

你只要不断的修改pages的数值就能获取到不同页数的主播列表,这其中就拥有房间号,观看人数,主播ID等信息,只要对这些信息进行处理,就能获取到你想要的信息

介绍工具

接下来介绍一下我使用的主要工具

superagent用于抓取HTML页面,cheerio用于对页面进行处理,获取信息。而ep实质上是一个非常好用的计数器,每当额定计数达到要求就触发回调函数。