实现一个简易爬虫&启动定时任务

课程介绍看这里:https://www.cnblogs.com/zhangran/p/11963616.html
项目github地址:https://github.com/hellozhangran/happy-egg-server

爬虫

目前 node.js 爬虫工具比较火的有 node-crawler puppeteer。不过我目前没打算用这些,因为至少现在我们的项目还用不到。只要能发送请求、解析dom我们就能自己实现一个爬虫。所以我选择了axios + cheerio来自己写爬虫。

获取博客园的推荐文章

首先我们用 axios + cheerio 来获取博客园的首页编辑推荐文章,并解析出这篇文章的正文部分。

// controller/crawler.js 文件
const axios = require('axios');
const cheerio = require('cheerio');
// articleCtrl是一个写好了的controller,里面有存储数据到mongo的逻辑。
const articleCtrl = require('./article');

async function cnblogs () {
    const res = await axios.get('https://www.cnblogs.com/');
    // 把axios得到的数据用cheerio解析,解析后的$对象拥有jquery的能力,可以通过jquery api直接操作dom
    const $ = cheerio.load(res.data);
    const $href = $('#editor_pick_lnk');
    let name = $href.text();
    // 找到编辑推荐文章的url,继续访问该页面
    let href = $href.attr('href');

    const subRes = await axios.get(href);
    const $$ = cheerio.load(subRes.data);
    // 获得编辑推荐文章的正文部分的html
    const bodyStr = $$('#cnblogs_post_body').html();
    // 存入mongodb,具体articleCtrl.create方法的实现可以从项目源码中看,位置express/controller/article.js
    const cRes = await articleCtrl.create({
        from: 'cnblogs',
        title: name,
        article: bodyStr,
        hot_level: 1,
        favor: 1,
        comment: 1
    });
};

module.exports = {
    cnblogs
};

通过上面简单的代码,我们就能把博客园的推荐文章正文部分存到数据库。接下来要创建定时任务,把每天的推荐文章都存到自己的数据库了。

定时任务

实例

定时任务工具我选择 node-schedule ,先上实例,后面再详细讲下用法。

// schedule/index.js 文件
var schedule = require('node-schedule');

// 可以按照cron的格式设置
function runSchedule (cb) {
    // cron风格的配置:每天上午10点执行一次
    schedule.scheduleJob('0 0 10 * * *', function () {
        console.log('定时任务执行一次');
            cb && cb();
    });
    // object风格的配置:每天上午10点执行一次
    // 注意,这里需要加minute:0, 否则10点的每一分钟都执行一次。
    schedule.scheduleJob({hour: 10, minute: 0}, function () {
        console.log('定时任务执行一次');
            cb && cb();
    });
}

module.exports = runSchedule;

接下来讲讲 cron 与 object 两种配置风格的差异。

建议大家直接用 cron 风格的配置方式。当我第一次看到 object 配置风格的时候也觉得很人性化,可用过后会发现坑太多,越用成本越大。不信可以慢慢看

object风格

// 每天上午7点的每分钟都执行一次 (本以为会每天7点执行一次)
let obj = { hour: 7};

// 同上
let obj = { hour: 7, minute: null};

// 上午7点整执行一次
let obj = { hour: 7, minute: 0};

// 每秒执行一次
let obj = { second: null }

// 每分钟执行一次
let obj = { hour: null }; // 费解,这个不应该是每小时执行一次吗

// 每分钟执行一次
let obj = { minute: null };

// 每小时执行一次
let obj = { hour: null, minute: 0 }

cron风格定时器

  • * * * * * * 每秒执行一次
  • 0 * * * * * 每分钟的第0秒执行一次
  • 0 0 * * * * 每小时的0分0秒执行一次
  • 0 0 7 * * * 每天早上7点的0分0秒执行一次
  • 0 0 7 1 * * 每月的1日早上7点0分0秒执行一次
  • 0 0 7 * * 1 每周1的早上7点0分0秒执行一次

对比完了这两种风格能明显的看出:虽然 object 更人性化但个人觉的有点中看不中用的感觉。尤其是对于个性化的配置,object 显的很蹩脚,而且你根本没法查,没那么多使用说明给到你。相比下 cron 本身就是linux的通用定时任务,各种玩法都被人用了多少遍了。

启动定时任务

最后,在 app.js 补上下面的逻辑,node app.js 启动服务,等待定时任务的执行吧。

const runSchedule = require('./schedule');
const crawlerCtrl = require('./controller/crawler');

function listen () {
    app.listen('3000', () => {
        console.log('listen: 3000');
        // 开启自动脚本
        runSchedule(function() {
            crawlerCtrl.cnblogs();
        })
    });
}

完整的逻辑去项目里翻代码吧。

【重学Node.js 第4篇】实现一个简易爬虫&启动定时任务的更多相关文章

  1. 【重学Node.js 第5篇】部署项目到腾讯云服务器

    课程介绍看这里:https://www.cnblogs.com/zhangran/p/11963616.html 项目github地址:https://github.com/hellozhangran ...

  2. 【重学Node.js 第3篇】mongodb以及mongoose的使用

    mongodb以及mongoose的使用 本篇为这个系列的第三篇,想看更多可以直接去github的项目:https://github.com/hellozhangran/happy-egg-serve ...

  3. 打算写一个《重学Node.js》系列,希望大家多多支持

    先放上链接吧,项目已经开始2周了:https://github.com/hellozhangran/happy-egg-server 想法 现在是2019年11月24日,还有人要开始学习Node.js ...

  4. 【重学Node.js 第1&2篇】本地搭建Node环境并起RESTful Api服务

    本地搭建Node环境并起RESTful Api服务 课程介绍看这里:https://www.cnblogs.com/zhangran/p/11963616.html 项目github地址:https: ...

  5. 学习node.js 第4篇 建立一个最小的web聊天系统

    我们生活在一个实时的世界里,有什么比聊天更加实时吗?那就让我们先写一个基于TCP 的聊天服务器吧,并且支持Telnet 连接.这很容易,而且能够完全用Node来编写.首先,我们需要在Node 中包含T ...

  6. Node.js Stream-基础篇

    Node.js Stream - 基础篇 邹斌 ·2016-07-08 11:51 背景 在构建较复杂的系统时,通常将其拆解为功能独立的若干部分.这些部分的接口遵循一定的规范,通过某种方式相连,以共同 ...

  7. 一目了然的 Node.js Windows10 安装篇

    本篇文章 介绍 NodeJS 的安装 及环境变量配置 Node JS 的 了解 1.Node.js简介 简单的说 Node.js 就是运行在服务端的 JavaScript.Node.js 是一个基于 ...

  8. 利用Node.js的Net模块实现一个命令行多人聊天室

    1.net模块基本API 要使用Node.js的net模块实现一个命令行聊天室,就必须先了解NET模块的API使用.NET模块API分为两大类:Server和Socket类.工厂方法. Server类 ...

  9. Node.js简单介绍并实现一个简单的Web MVC框架

    编号:1018时间:2016年6月13日16:06:41功能:Node.js简单介绍并实现一个简单的Web MVC框架URL :https://cnodejs.org/topic/4f16442cca ...

随机推荐

  1. [C#] 如何分析stackoverflow等clr错误

    有时候由于无限递归调用等代码错误,w3wp.exe会报错退出,原因是clr.exe出错了. 这种错误比较难分析,因为C#代码抓不住StackOverflowException等异常. 处理方法是:生成 ...

  2. vue element 中自定义传值

    一直以来都不知道如何传自定义的值,一直只会默认的,今天终于找到方法了. 比如这个上传图片的控件,想带当前的index过去,就这样写.其它的类似 :http-request="(file,fi ...

  3. python基础之逻辑题(1)

    python基础之逻辑题(1) 1.用一行代码实现数值交换? 2.求结果--fromkeys? 3.1,2,3,4,5能组成多少个互不相同且无重复的三位数? 4.有两个字符串列表a和b,每个字符串是逗 ...

  4. 开源中国 2014 最受关注开源软件排行榜 TOP 50

    开源中国 2014 最受关注开源软件排行榜 TOP 50 开源中国 2014 年最受关注软件排行榜 TOP 50 正式出炉!2014 年结束了,我们来了解一下过去一年里开源中国最受欢迎的 50 款软件 ...

  5. hdu 2410 Barbara Bennett's Wild Numbers

    Problem - 2410 挺好玩的一道题目.这道题的意思是给出一个模糊值以及一个确定值,要求求出模糊值中大于确定值的个数有多少. 这题我是直接用dfs的方法搜索的,对于每一位如果之前位置的形成的数 ...

  6. 为 Ubuntu 18.04 添加开机自动加载 ntfs分区 功能

    注意:Ubuntu终端命令是区分大小写的 1,准备的:     ntfs-3g -- 提供ntfs读写支持(一般说来是自带的,若没有,可是使用 sudo apt-get isntall ntfs-3g ...

  7. 手机QQ浏览器属于代理服务器吗?

    这两天.上QQ,会员上线提示.老是显示福建省,而没有具体的地方.这是怎么回事呢?而且那个时间段我都没有上QQ.但是有用手机QQ浏览器.偷菜.这是怎么回事,机子也没有病毒 没有木马 到底怎么搞的...! ...

  8. 【原生JS】制作网页头部刷新进度条

    之前的某次番啬看到油管上有这么一个进度条,当时觉得挺好玩,一直想着做一个试试,刚才弄了一下写了一个不算太好看的简陋版本,哈哈. (本博客刷新会头部会出现,因为并没有真正的参与到浏览器加载是否完整这个渲 ...

  9. Activity学习(一):生命周期

    一. 认识Activity Activity是Android的四大组件之一,那么它是什么呢?如果简单的理解,可以把它当成应用的一个显示的屏幕. Activity类处于android.app包中,继承体 ...

  10. 2019-8-31-dotnet-core-黑科技·String.IndexOf-性能

    title author date CreateTime categories dotnet core 黑科技·String.IndexOf 性能 lindexi 2019-08-31 16:55:5 ...