使用Nodejs怎么编写一个定时爬虫

使用Nodejs怎么编写一个定时爬虫?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

constaxios=require('axios')
constroomid="146088"
construid="642922"
consturl=`https://api.live.bilibili.com/xlive/app-room/v2/guardTab/topList?roomid=${roomid}&ruid=${ruid}&page_size=30`

constCaptin={
1:'总督',
2:'提督',
3:'舰长'
}

constreqPromise=url=>axios.get(url);

letCaptinList=[]
letUserList=[]

asyncfunctioncrawler(URL,pageNow){
constres=awaitreqPromise(URL);
if(pageNow==1){
CaptinList=CaptinList.concat(res.data.data.top3);
}
CaptinList=CaptinList.concat(res.data.data.list);
}


functiongetMaxPage(res){

constInfo=res.data.data.info
const{page:maxPage}=Info
returnmaxPage
}


functiongetUserList(res){

for(letitemofres){
constuserInfo=item
const{uid,username,guard_level}=userInfo
UserList.push({uid,username,Captin:Captin[guard_level]})
}
}

asyncfunctionmain(UID){
constmaxPage=awaitreqPromise(`${url}&page=1`).then(getMaxPage)
for(letpageNow=1;pageNow<maxPage+1;pageNow++){
constURL=`${url}&page=${pageNow}`;
awaitcrawler(URL,pageNow);
}
getUserList(CaptinList)
console.log(search(UID,UserList))
returnsearch(UID,UserList)
}

functionsearch(uid,UserList){
for(leti=0;i<UserList.length;i++){
if(UserList[i].uid===uid){
returnUserList[i];
}
}
return0
}

module.exports={
main
}

很明显这个爬虫只能手动触发,直接跑还需要个命令行和node环境,于是就给他用Koa2开了个页面服务,写一个极其简陋的页面

使用Nodejs怎么编写一个定时爬虫

constKoa=require('koa');
constapp=newKoa();
constpath=require('path')
constfs=require('fs');
constrouter=require('koa-router')();
constindex=require('./index')
constviews=require('koa-views')



app.use(views(path.join(__dirname,'./'),{
extension:'ejs'
}))
app.use(router.routes());

router.get('/',asyncctx=>{
ctx.response.type='html';
ctx.response.body=fs.createReadStream('./index.html');
})

router.get('/api/captin',async(ctx)=>{
constUID=ctx.request.query.uid
console.log(UID)
constInfo=awaitindex.main(parseInt(UID))
awaitctx.render('index',{
Info,
})
});

app.listen(3000);

由于页面没有节流防抖,当前版本又只能实时爬取,等待时间较长,频繁刷新自然会触发b站的反爬虫机制,于是当前服务器ip就被风控了。

于是bilibili-live-captain-tools 2.0横空出世

functionthrottle(fn,delay){
vartimer;
returnfunction(){
var_this=this;
varargs=arguments;
if(timer){
return;
}
timer=setTimeout(function(){
fn.apply(_this,args);
timer=null;//在delay后执行完fn之后清空timer,此时timer为假,throttle触发可以进入计时器
},delay)
}
}

再添加节流防抖的同时,使用伪实时爬虫(通过定时任务一分钟爬取一次)

这种情况我们需要去定时执行爬虫脚本了,这个时候我就想到了就可以利用egg的schedule功能了,可是不想让一个爬虫程序如此“大材小用”,遇事不决,百度一下。于是就有了下面的方案

使用 Node Schedule 实现定时任务

Node Schedule是用于Node.js的灵活的cron类和非cron类作业调度程序。 它允许您使用可选的重复规则来计划作业(任意函数),以在特定日期执行。 它在任何给定时间仅使用一个计时器(而不是每秒钟/分钟重新评估即将到来的作业)。

一、安装 node-schedule

npminstallnode-schedule
#或
yarnaddnode-schedule

二、基本用法

一起啊看一下官方给的例子

constschedule=require('node-schedule');

constjob=schedule.scheduleJob('42****',function(){
console.log('Theanswertolife,theuniverse,andeverything!');
});

schedule.scheduleJob 的第一个参数需要如下按照规则输入

Node Schedule规则按下表表示

* * * * * *┬ ┬ ┬ ┬ ┬ ┬│ │ │ │ │ |│ │ │ │ │ └ 星期几,取值:0 - 7,其中 0 和 7 都表示是周日│ │ │ │ └─── 月份,取值:1 - 12│ │ │ └────── 日期,取值:1 - 31│ │ └───────── 时,取值:0 - 23│ └──────────── 分,取值:0 - 59└─────────────── 秒,取值:0 - 59(可选)也可以指定一个具体的时间,如:const date = new Date()

看懂规则我们自己实现一个

constschedule=require('node-schedule');

//定义一个时间
letdate=newDate(2021,3,10,12,00,0);

//定义一个任务
letjob=schedule.scheduleJob(date,()=>{
console.log("现在时间:",newDate());
});

上面的例子就代表到2021年3月10日12点的时候执行报时

三、高级用法

除了基础的用法,我们还可以使用一些更为灵活的方法来实现定时任务。

3.1、隔一分钟执行一次

constschedule=require('node-schedule');

//定义规则
letrule=newschedule.RecurrenceRule();
rule.second=0
//每分钟0秒执行一次

//启动任务
letjob=schedule.scheduleJob(rule,()=>{
console.log(newDate());
});

rule 支持设置的值有 second、minute、hour、date、dayOfWeek、month、year 等。

一些常见的规则如下表

每秒执行rule.second = [0,1,2,3......59];每分钟 0 秒执行rule.second = 0;每小时 30 分执行rule.minute = 30;rule.second = 0;每天 0 点执行rule.hour =0;rule.minute =0;rule.second =0;每月 1 号的 10 点执行rule.date = 1;rule.hour = 10;rule.minute = 0;rule.second = 0;每周一、周三、周五的 0 点和 12 点执行rule.dayOfWeek = [1,3,5];rule.hour = [0,12];rule.minute = 0;rule.second = 0;

四、终止任务

可以使用 cancel() 终止一个运行中的任务。当任务出现异常及时取消终止任务

job.cancel();

关于使用Nodejs怎么编写一个定时爬虫问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注恰卡编程网行业资讯频道了解更多相关知识。

发布于 2021-03-13 15:41:10
收藏
分享
海报
0 条评论
170
上一篇:python openpyxl如何筛选列 下一篇:使用R语言怎么删除/添加数据框中的某一行/列
目录

    0 条评论

    本站已关闭游客评论,请登录或者注册后再评论吧~

    忘记密码?

    图形验证码