github源代码
首先介绍一下我引用的包
require(“request”); –get post请求页面
require(“cheerio”) –解析文本对象为DOM对象 也就是说将string 装换为 js操作的 $() 这种选择器
require(‘fs’); – 将数据保存json格式
require(“async”) –流程控制 主要是控制抓取时间间隔
require(‘sequelize’); –保存到数据库用的
require(‘log4js’) –log日志管理
这张图片是项目目录
./bin 日志配置
./logs 日志目录
,/model mongodb 实体
./output json输出目录
index.js 启动项 node.exe index.js
douyu.js 抓取斗鱼
接下来介绍思路:
第一步 分析页面(找到在线直播的url)
第二步 使用require 请求页面 获取html文档
第三步 使用cheerio 分析页面
第四步 保存数据到 json.js 文档 mysql mongodb
介绍代码
外层
我们看一下 douyu.js
var request = require("request");
//文档分析
var cheerio = require("cheerio");
var fs = require('fs');
//日志
var logger = require("./bin/logHelper").helper;
//流程控制
var async = require("async");
//数据库访问
var Sequelize = require('sequelize');
var data_db= new Sequelize(
"UserInfo",
"sa",
"pass1234",{
dialect:'mssql',
host:'127.0.0.1',
port:1433
}
);
//mongodb访问
var _mongodb = require('./model/mongodb');
流程控制 async
//流程控制 async
async.waterfall([
function(cb){
//获取总页数,直接get请求
request('https://www.douyu.com/directory/all', function (error, response, body) {
//获取总页数
if (!error && response.statusCode == 200) {
var $ = cheerio.load(body, {
normalizeWhitespace: true,
decodeEntities: false
});
var num = $(".classify_li a").eq(0).attr("data-pagecount");
cb(null,num);
}
})
},
function(num,cb){
var opts = [];
for (var i = 1; i 'GET',
url: url,
qs: {page: i, isAjax: 1}
});
}
//2秒抓一次
// async.eachSeries(opts,function (opt, callback) {
// setTimeout(function(){
// fetchPage(opt, (err) => {callback()});
// }, 2000);
// }
// );
//控制最大并发数为5,
async.forEachLimit(opts,5,function (opt, callback) {
setTimeout(function(){
fetchPage(opt, (err) => {callback()});
}, 2000);
},function (err) {
if (err) {
logger.writeErr(err);
cb(err);
} else {
logger.writeInfo("douyu抓取结束");
console.log("douyu抓取结束");
cb();
}
}
);
}
]);
分析页面
function fetchPage(opt, cb) {
console.log("抓取第" + opt.qs.page+"页");
request(opt, function (error, response, body) {
if (error) {
return;
}
var $ = cheerio.load(body, {
normalizeWhitespace: true,
decodeEntities: false
});
var items = [];
var itemsstr = [];
logger.writeInfo("抓取第" + opt.qs.page+"页");
$("li").each(function (index, el) {
var dyNum =$(el).find('.dy-num.fr').text();
if(dyNum.indexOf('万')>=0){
dyNum =Number(dyNum.replace('万',''))*10000;
}
var item = {
userid: $(el).find('a.play-list-link').attr("data-rid"),
userName: $(el).find('.dy-name.ellipsis.fl').text(),
tag: $(el).find('.tag.ellipsis').text(),
dyNum: dyNum,
title:$(el).find('a.play-list-link').attr("title"),
url:"https://www.douyu.com"+$(el).find('a.play-list-link').attr("href")
};
items.push(item);
});
// var sql="INSERT INTO [dbo].[douyu]([userid],[userName],[tag],[dyNum] ,[title],[url],[SpideTiem]) VALUES " ;
// for(var vue of items){
// itemsstr.push("('"+vue.userid+"','"+vue.userName+"','"+vue.tag+"','"+vue.dyNum+"','"+vue.title+"','"+vue.url+"',GETDATE())")
// }
if(items.length>0) {
//插入mssql
// data_db.query(sql+itemsstr.toString()).then(function (q) {
// console.log("插入第" + opt.qs.page+"页");
// cb();
// });
//json格式
// fs.writeFile('output/output'+opt.qs.page+'.json', JSON.stringify(items, null, 2), function (err) {
// console.log("插入第" + opt.qs.page+"页");
// cb();
// });
//使用mongoDB保存
// _mongodb.douyuModel.collection.insert(items,function(err){
// if(err){
// console.log(err);
// }else{
// console.log("插入第" + opt.qs.page+"页");
// cb();
// }
// })
}
});
}
接下来就是数据分析和echarts数据展示了,还没弄额
可以直接到github源代码
下载代码或者加qq群一起交流:315552185