使用Nodejs怎么编写一个定时爬虫
使用Nodejs怎么编写一个定时爬虫?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。
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点的时候执行报时
三、高级用法
除了基础的用法,我们还可以使用一些更为灵活的方法来实现定时任务。
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();
关于使用Nodejs怎么编写一个定时爬虫问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注编程网行业资讯频道了解更多相关知识。
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341