近几年直播能够说是至关火爆,可是直播间里动辄成百上千万的人气让人禁不住产生疑惑,怎么会有这么高的人气?难道全国人民都在看直播?javascript
为了解决这个困扰我已久的问题,我专门去学习了node爬虫的相关知识,下面就跟你们分享一下。php
先从日常看的最多的斗鱼开始,后来也证实斗鱼是最简单的一个。css
经过去分析斗鱼的网站发现,斗鱼有一个所有分类的页面https://www.douyu.com/directory
html
在这里用到了cheerio
这个包,这个包就至关于服务端的jQuery,用在服务器端须要对DOM进行操做的地方,使用方法也跟jQuery差很少。java
由于斗鱼的网页通过了gzip压缩,还要用到zlib
,这个包的做用是解压缩。node
// 引入https模块
const https = require('https')
// zlib包,用于解压缩
const zlib = require('zlib')
// cheerio包,提供了相似jQuery的功能
const cheerio = require("cheerio");
function douyu () {
// 建立请求对象
let req = https.request('https://www.douyu.com/directory', res => {
// 接收数据
let chunks = []
// 监听到数据就存储起来
res.on('data', chunk => {
chunks.push(chunk)
})
// 数据传输结束
res.on('end', () => {
// 拼接数据
var buffer = Buffer.concat(chunks)
// 使用zlib解压缩
zlib.gunzip(buffer, function (err, decoded) {
// gzip解压后的html文本
let html = decoded.toString()
// 使用cheerio解析html
let $ = cheerio.load(html)
// 获取包含直播数据的元素列表
let list = $('#allCate .layout-Module-container .layout-Classify-list .layout-Classify-item .layout-Classify-card')
// 解析dom,取出标签中的数据
const dataList = {}
Array.prototype.map.call(list, item => {
let key = '', value = ''
item.children.forEach(childrenItem => {
if (childrenItem.name === 'strong') {
key = childrenItem.children[0] ? childrenItem.children[0].data : '空'
} else if (childrenItem.name === 'div') {
value = $(childrenItem).find('span').html()
value = unescape(value.replace(/&#x/g, '%u').replace(/;/g, ''))
}
})
dataList[key] = value
})
// 相加得出总人数
let total = 0
for (let key in dataList) {
let value = dataList[key]
// 处理单位为万的数字
if (value.indexOf('万') != -1) value = Number.parseFloat(value) * 10000
total += Number.parseFloat(value) ? Number.parseFloat(value) : 0
}
console.log(`斗鱼:${total}`)
})
})
})
// 发送请求
req.end()
}
复制代码
查看虎牙的网站发现并无像斗鱼同样提供统计的分类列表,可是找到了该网站查询直播间列表信息的接口https://www.huya.com/cache.php?m=LiveList&do=getLiveListByPage&tagAll=0&page=1
。经过该接口能够拿到全部直播间的信息,其中就包含了每一个直播间的人数,接下来就是把每一个直播间的人数相加就能够获得该平台的总人数。web
// 引入https模块
const https = require('https')
function huya {
// 初始化总数
let total = 0
// 初始化总页数
let totalPage = 1
// 初始化当前页数
let currentPage = 1
// 与斗鱼同样的开始获取、处理数据
huyaGetData(currentPage)
function huyaGetData(currentPage) {
let req = https.request(`https://www.huya.com/cache.php?m=LiveList&do=getLiveListByPage&tagAll=0&page=${currentPage}`, res => {
const chunks = []
res.on('data', chunk => {
chunks.push(chunk)
})
res.on('end', () => {
const data = JSON.parse(Buffer.concat(chunks).toString('utf-8')).data
const dataList = data.datas
// 拿到总页数
totalPage = data.totalPage
// 累加直播间的人数
total = dataList.reduce((total, item) => {
return total + Number.parseInt(item.totalCount)
}, total)
// 获取下一页的数据
currentPage += 1
if (currentPage < totalPage) {
huyaGetData(currentPage)
} else {
console.log(`虎牙:${total}`)
}
})
})
req.end()
}
}
复制代码
哔哩哔哩页面中也有与虎牙类似的所有直播间查询接口,统计方法与虎牙差很少,这里就再也不赘述了。chrome
在YY的网页中并无提供所有直播间的查询接口,只提供了单一分类的查询接口https://www.yy.com/more/page.action?biz=sing&subBiz=idx&page=3&moduleId=308&pageSize=60
,而每一个分类查询要传过去的参数值都不同,又没有任何规律可循,因此如今要拿到每一个分类查询所须要的信息,以后的查询就跟虎牙同样了。api
那如今要作的就是拿到接口所需信息,经过分析页面发现每一个分类直播的列表页都有一个pageInfo
的全局变量,这里边就包含了查询所需的全部信息。咱们能够拿到这些分类页面的html
文件,而后解析出其中的pageInfo变量。可是这里为了演示,咱们使用另外一个方法Selenium
来解决这个问题。浏览器
Selenium
是一个Web应用的自动化测试框架,用在爬虫中可使用它打开浏览器,用代码去模拟人的真实操做去爬取须要的信息,突破反爬虫手段的限制。
要使用Selenium
,首先要根据平台去下载对应的webdriver
,这里
是chromeDriver
的下载地址,根据本身电脑上Chrome
的版本下载对应的chromeDriver
,下载好以后复制到项目根目录。别的浏览器能够自行去找对应的包下载。
而后在项目中安装selenium-webdriver
包的依赖。
const { Builder, By } = require('selenium-webdriver')
async function getYYPageInfoList() {
// 构建WebDriver对象
let driver = await new Builder().forBrowser('chrome').build();
// 打开网页
await driver.get('https://www.yy.com/catalog');
// 获取分类标签列表
let aList = await driver.findElements(By.css('.w-video-module-cataloglist a'))
// 获取分类页面地址列表
let hrefList = []
for (let i = 0; i < aList.length - 1; i++) {
let href = await aList[i].getAttribute('href')
hrefList.push(href)
}
// 打开分类页面
for (let i = 0; i < hrefList.length - 1; i++) {
await driver.get(hrefList[i])
// 在页面中执行 return pageInfo, 取到pageInfo
driver.executeScript('return pageInfo').then(function (obj) {
// 存储pageInfo信息
pageInfoList.push(obj)
})
}
// 退出浏览器
driver.quiet()
return pageInfoList
}
复制代码
统计结果的地址:http://liupenglong.com/live/index.html
(每五分钟统计一次)
能够看到目前仅仅统计出了斗鱼、虎牙、哔哩哔哩、YY的数据,总人数已经超过全国总人口了,算上别的没有统计上的。。。结果可想而知,估计全球人民都在看中国的直播了。
接下来有时间会把别的平台的也统计出来,最终但愿能推算出来真正在看直播的人数,你们若是有什么好的想法能够评论交流一下。