我很喜歡 Soft & Share 特價課程與學習資訊分享 這個社團,因為他分享了許多免費學習的資訊,很多課程都令人愛不釋手。而我們到 Udemy 的搜尋裡面,也能輕易地找出許多免費課程,不過這個跟 Soft & Share 社團所分享的不太一樣,因為社團所分享的是包含透過 coupon 所拿到的免費課程。那麼我們今天的就來試試看有沒有什麼方式能夠取得 frees coupon course,然後做一個訂閱限時免費課程的服務。
我們先 google 看看 「udemy free coupon」,當然就會看到許多 coupon 網站,在查看結果的過程中眼尖發現到 reddit 這個國外最大的論壇。若說台灣資訊流竄最快的肯定是 ptt,那麼在國外肯定就是 reddit,那麼我們就去 reddit 看看有沒有適合的看板。
直接搜尋 udemy 會看到三個看板,第一個比較像是 Udemy 的討論論壇,而第二、三個就是我們想要的 free coupon course。點進去看看,沒錯,就是我們想要的,若我們能夠定期的取得最新的,我們就可以將著個服務建立起來。
接著繼續觀察每一個項目,很幸運的,每個 dom 都有包含 timestamp,也就是說,我們能夠制定我們的 cron job,在間隔一段時間抓取這個時間區間內的新文章,如此一來應該就能完成訂閱服務。
若要抓取所有區間內的新文章,我們需要做以下兩個步驟:
我們先用 postman 對看板的 url 抓看看,確定是可以拿到列表,然後用 select 選取看看,確認是可以把文章列表抓出來。
接下來來對文章列表做篩選,我們先假設爬蟲三天執行一次,所以預設先抓取三天內的文章,試著 filter 看看,確定是可以篩選出時間內的文章。
我們先來撰寫取得文章列表的 function,接受一個 url 參數,用 request 取得列表,整理一下資料,再做 timestamp filter,最後用 promise resolve 我們取得的文章。另外我們也設定一下 const PERIOD,方便我們未來做調整。
const PERIOD = 60 * 60 * 24 * 3 * 1000;
function getNewPost(url) {
return new Promise(done => {
request(url, (err, res, body) => {
var $ = cheerio.load(body)
var posts = $('.thing').map((index, obj) => {
return {
title: $(obj).find('a.title').text(),
link: $(obj).find('a.title').attr('href'),
timestamp: $(obj).attr('data-timestamp'),
}
}).get().filter((obj) => {
return obj.timestamp > (Date.now() - PERIOD)
})
done(posts)
})
})
}
因為有兩個看板,所以我們用 promise.all 來取得時間區間內的文章列表,然後在做 array flat,這樣就完成了。
Promise.all([
getNewPost('https://www.reddit.com/r/udemyfreecourses/'),
getNewPost('https://www.reddit.com/r/udemyfreebies/')
]).then(results => {
console.log([].concat.apply([], results));
});
const request = require('request');
const cheerio = require('cheerio');
const PERIOD = 60 * 60 * 24 * 3 * 1000;
Promise.all([
getNewPost('https://www.reddit.com/r/udemyfreecourses/'),
getNewPost('https://www.reddit.com/r/udemyfreebies/')
]).then(results => {
console.log([].concat.apply([], results));
});
function getNewPost(url) {
return new Promise(done => {
request(url, (err, res, body) => {
var $ = cheerio.load(body)
var posts = $('.thing').map((index, obj) => {
return {
title: $(obj).find('a.title').text(),
link: $(obj).find('a.title').attr('href'),
timestamp: $(obj).attr('data-timestamp'),
}
}).get().filter((obj) => {
return obj.timestamp > (Date.now() - PERIOD)
})
done(posts)
})
})
}
許多的資訊都是藉由論壇或社群所討論出來,但這類的資料通常都缺乏整理,所以幾乎都是散亂的,而我們可以利用爬蟲做定期整理,就有機會將這些討論串變成很有用的資料。
除了把文章列表拿取出來以外,我們還可以對文章內容做格式整理,或者在關鍵字訂閱,這樣也能夠做成很有用的服務。若更近一步,我們可以自動將這些課程加入我們的 Udemy 的帳號,那就能做到完全自動化訂閱限時免費的課程。
大大的爬蟲教學看下來
發現比source code 更寶貴的是
文章融入了
如何發現問題—>解決問題的思維
受益良多
Good job 謝謝分享
後續補充:
由於reddit網站更新改版的緣故,需將以下程式碼
Promise.all([
getNewPost('https://www.reddit.com/r/udemyfreecourses/'),
getNewPost('https://www.reddit.com/r/udemyfreebies/')
]).then(results => {
console.log([].concat.apply([], results));
});
改為
Promise.all([
getNewPost('https://old.reddit.com/r/udemyfreecourses/'),
getNewPost('https://old.reddit.com/r/udemyfreebies/')
]).then(results => {
console.log([].concat.apply([], results));
});
方能爬得到資料哦!