作為費德勒的鐵桿粉絲,每天早上都會在新浪體育里面的網球頻道瀏覽費德勒新聞。由於只關注費德勒的新聞,所以每次都要在網頁中大量的新聞中篩選相關信息,感覺效率好低,所以用node寫了一個簡單的爬蟲程序通過每天定時發送郵件的方式來通知。
這個需求仔細看有3個功能點,信息爬蟲,定時發送,郵件通知
信息爬蟲
信息爬蟲建立在對頁面結構的分析,從頁面內容中抽取符合我們需要的信息,所以我們在獲得網頁信息后,需要對dom結構進行分析,獲得相關信息,組裝成數據。
Axios(https://github.com/mzabriskie/axios) 是一個基於 promise 的 HTTP 庫,可以用在瀏覽器和 node.js 中發送請求,獲取數據,所以我們通過可以axios來獲取html頁面內容
接下來,我們需要分析html內容中,cheerio(https://github.com/cheeriojs/cheerio)這個庫可以幫我們像jquery的API一樣分析獲取dom結構,進行數據的篩選。
所以對於網頁的爬蟲,我們實現思路,axios獲取數據,cheerio獲取整個頁面的A的標簽,在對A標簽的內容進行正則匹配篩選,存儲到數組中,具體代碼如下:
const KEYWORD = '費德勒'; const KEYWORD_REG = new RegExp(KEYWORD, 'i'); let newsArry = []; function spider() { return axios.get('http://sports.sina.com.cn/tennis/').then(response => { if (response.status === 200) { let $ = cheerio.load(response.data, { decodeEntities: false }); let newsList = $('a[href]'); newsArry = []; for (let i = 0; i < newsList.length; ++i) { let obj = $(newsList[i]); let text = $(newsList[i]).text(); //收集數據 if (KEYWORD_REG.test(text)) { newsArry.push({ 'title': text.trim(), 'href': obj.attr('href') }) } } } }).catch(e => { console.log('爬蟲失敗了'); console.log(error); })
郵件通知
nodemailer(https://nodemailer.com/)是一個關於郵件發送的庫,只要安裝nodemailer模塊,按照規則配置好發送信息即可,代碼如下:
const configData = require('./config.json'); //生成發送字符串 function formStr(arr) { let html = ''; for (let data of arr) { html += `<p><a target="_blank" href="${data.href}">${data.title}</a></p>` // red green blue } return html; } //郵件發送函數 function sendEmail(opts) { let transporter = nodemailer.createTransport({ service: 'QQ', auth: configData.auth }, { from: configData.auth.user }) var message = { //收件人用逗號間隔 to: opts.to, //信息主題 subject: opts.subject, //內容 html: opts.html };
auth 中的 pass,是指“郵箱第三方登錄授權碼”,如何獲取授權碼,以QQ郵箱為例,請點擊:http://jingyan.baidu.com/article/fedf0737af2b4035ac8977ea.html
定時發送
定時發送我們可以通過簡單的setInterval來實現,但是這樣寫的擴展性不高。到node社區搜了一下,發現了一個定時腳本庫:node-schedule(https://www.npmjs.com/package/node-schedule)
const schedule = require('node-schedule'); const SCHEDULE_RULE = '1 30 10 * * *'; //每天10點30分發送 schedule.scheduleJob(SCHEDULE_RULE, () => { spider().then(() => { sendEmail({ to: configData.recipients.join(','), subject: `${KEYWORD}新聞`, html: formStr(newsArry) }) }); });
這個庫的使用和簡單,指定匹配規則,然后添加定時執行函數就可以了。
我們這里指定規則每天10點半發送郵件,這樣我們也完成了定時發送的任務
我們來看一下發送到我們郵箱數據:
大功告成,這樣我們以后每天10點半直接看郵件就行了。