Nodejs实现定时爬虫的完整实例

 更新时间:2021年03月12日 11:01:17   作者:咸鱼爱前端  
这篇文章主要给大家介绍了关于Nodejs实现定时爬虫的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

事件起因

前两天要帮朋友B站舰长群审核,一个个去舰长列表查找,自然不是一个程序猿的首选,把任务交给计算机让他自己做,摸鱼才是正道。理论成立开始Coding .

由于已知舰长列表的 API 爬虫使用 Axios 直接访问接口

于是花了亿点点时间写完了这段爬虫我称之为bilibili-live-captain-tools 1.0

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

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

const reqPromise = url => axios.get(url);

let CaptinList = []
let UserList = []

async function crawler(URL, pageNow) {
 const res = await reqPromise(URL);
 if (pageNow == 1) {
 CaptinList = CaptinList.concat(res.data.data.top3);
 }
 CaptinList = CaptinList.concat(res.data.data.list);
}


function getMaxPage(res) {

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


function getUserList(res) {

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

async function main(UID) {
 const maxPage = await reqPromise(`${url}&page=1`).then(getMaxPage)
 for (let pageNow = 1; pageNow < maxPage + 1; pageNow++) {
 const URL = `${url}&page=${pageNow}`;
 await crawler(URL, pageNow);
 }
 getUserList(CaptinList)
 console.log(search(UID, UserList))
 return search(UID, UserList)
}

function search(uid, UserList) {
 for (let i = 0; i < UserList.length; i++) {
 if (UserList[i].uid === uid) {
 return UserList[i];
 }
 }
 return 0
}

module.exports = {
 main
}

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

const Koa = require('koa');
const app = new Koa();
const path = require('path')
const fs = require('fs');
const router = require('koa-router')();
const index = require('./index')
const views = require('koa-views')



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

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

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

app.listen(3000);

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

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

function throttle(fn, delay) {
 var timer;
 return function () {
 var _this = this;
 var args = 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

npm install node-schedule
# 或
yarn add node-schedule

二、基本用法

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

const schedule = require('node-schedule');

const job = schedule.scheduleJob('42 * * * *', function(){
 console.log('The answer to life, the universe, and everything!');
});

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

Node Schedule规则按下表表示

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

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

const schedule = require('node-schedule');

// 定义一个时间
let date = new Date(2021, 3, 10, 12, 00, 0);

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

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

三、高级用法

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

3.1、隔一分钟执行一次

const schedule = require('node-schedule');

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

// 启动任务
let job = schedule.scheduleJob(rule, () => {
 console.log(new Date());
});

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();

总结

node-schedule 是 Node.js 的一个 定时任务(crontab)模块。我们可以使用定时任务来对服务器系统进行维护,让其在固定的时间段执行某些必要的操作,还可以使用定时任务发送邮件、爬取数据等;

到此这篇关于Nodejs实现定时爬虫的文章就介绍到这了,更多相关Nodejs定时爬虫内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 使用nodejs实现JSON文件自动转Excel的工具(推荐)

    使用nodejs实现JSON文件自动转Excel的工具(推荐)

    这篇文章主要介绍了使用nodejs实现,JSON文件自动转Excel的工具,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-06-06
  • 解决Mac下安装nmp的淘宝镜像失败问题

    解决Mac下安装nmp的淘宝镜像失败问题

    今天小编就为大家分享一篇解决Mac下安装nmp的淘宝镜像失败问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-05-05
  • NodeJS实现图片文本分割

    NodeJS实现图片文本分割

    这篇文章主要为大家详细介绍了NodeJS实现图片文本分割,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • Node.js中path.resolve与path.join的区别与作用详解

    Node.js中path.resolve与path.join的区别与作用详解

    path.resolve和path.join都是属于path核心模块下的方法,用来拼接路径,下面这篇文章主要给大家介绍了关于Node.js中path.resolve与path.join的区别与作用的相关资料,需要的朋友可以参考下
    2023-03-03
  • windows系统下安装npm(Node.js)方法教程

    windows系统下安装npm(Node.js)方法教程

    在Windows环境下进行Node.js的安装并不是一件复杂的事情,但是在安装过程中需要注意一些细节,下面这篇文章主要给大家介绍了关于windows系统下安装npm(Node.js)的相关资料,需要的朋友可以参考下
    2023-12-12
  • node 解析图片二维码的内容代码实例

    node 解析图片二维码的内容代码实例

    这篇文章主要介绍了node 解析图片二维码的内容代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09
  • Node.js实现文件上传的示例

    Node.js实现文件上传的示例

    本篇文章主要介绍了Node.js实现文件上传的示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-06-06
  • 利用forever和pm2部署node.js项目过程

    利用forever和pm2部署node.js项目过程

    这篇文章主要给大家介绍了如何利用forever和pm2部署node.js项目的相关资料,文中给出了详细的介绍和示例代码供大家参考学习,相信对大家的学习或者工作具有一定的学习价值,需要的朋友们下面随着小编一起来看看吧。
    2017-05-05
  • Nodejs使用Mongodb存储与提供后端CRD服务详解

    Nodejs使用Mongodb存储与提供后端CRD服务详解

    这篇文章主要给大家介绍了关于Nodejs使用Mongodb存储与提供后端CRD服务的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-09-09
  • node文字生成图片的示例代码

    node文字生成图片的示例代码

    本篇文章主要介绍了node文字转图片的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10

最新评论