- 課程介紹看這裏:juejin.im/post/5df25c…
- 項目github地址:github.com/hellozhangr…
目前 node.js 爬蟲工具比較火的有 node-crawler
puppeteer
。不過我目前沒打算用這些,由於至少如今咱們的項目還用不到。只要能發送請求、解析dom咱們就能本身實現一個爬蟲。因此我選擇了axios + cheerio來本身寫爬蟲。javascript
首先咱們用 axios + cheerio 來獲取博客園的首頁編輯推薦文章,並解析出這篇文章的正文部分。html
// 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
};
複製代碼
經過上面簡單的代碼,咱們就能把博客園的推薦文章正文部分存到數據庫。接下來要建立定時任務,把天天的推薦文章都存到本身的數據庫了。java
定時任務工具我選擇 node-schedule
,先上實例,後面再詳細講下用法。node
// 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 兩種配置風格的差別。jquery
建議你們直接用 cron 風格的配置方式。當我第一次看到 object 配置風格的時候也以爲很人性化,可用事後會發現坑太多,越用成本越大。不信能夠慢慢看linux
// 天天上午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 }
複製代碼
* * * * * *
每秒執行一次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的通用定時任務,各類玩法都被人用了多少遍了。ios
最後,在 app.js
補上下面的邏輯,node app.js
啓動服務,等待定時任務的執行吧。git
const runSchedule = require('./schedule');
const crawlerCtrl = require('./controller/crawler');
function listen () {
app.listen('3000', () => {
console.log('listen: 3000');
// 開啓自動腳本
runSchedule(function() {
crawlerCtrl.cnblogs();
})
});
}
複製代碼
完整的邏輯去項目裏翻代碼吧。github