使用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开了个页面服务,写一个极其简陋的页面
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怎么编写一个定时爬虫问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注恰卡编程网行业资讯频道了解更多相关知识。
推荐阅读
-
NodeJS怎么实现单点登录
-
怎么用Vue+NodeJS实现大文件上传
-
node中的buffer有什么用
node中的buffer有什么用本文小编为大家详细介绍“node中...
-
node中multer的概念是什么
node中multer的概念是什么这篇文章主要介绍“node中mu...
-
nodejs怎么读取文件夹目录的内容
nodejs怎么读取文件夹目录的内容小编给大家分享一下nodejs...
-
nodejs如何结合socket.io实现websocket通信功能
这篇文章主要介绍nodejs如何结合socket.io实现websocket通信功能,文中介绍的非常详细,具有一定的参考价值,感兴...
-
nodejs如何结合Socket.IO实现的即时通讯功能
-
nodejs如何实现TCP服务器端和客户端聊天功能
这篇文章主要介绍了nodejs如何实现TCP服务器端和客户端聊天功能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇...
-
Nodejs能够应用于什么场景
这篇文章给大家分享的是有关Nodejs能够应用于什么场景的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。...
-
Nodejs +Websocket如何实现指定发送及群聊