昨天我們做抓了 NBA 的 scoreboard,那麼今天我們持續昨天的主題。博弈廠商除了要分數之外,他們還希望抓取新聞呈現在頁面中,讓使用者能夠取得額外的資訊,那麼我們今天就來抓取看看 NBA 的運動新聞。
NBA 的運動新聞來源就非常多了,我們在 google 類搜尋 nba 新聞
至少可以看到有十幾個 source 來源,那麼當我們的資料挑選來源非常廣泛時,我們就盡可能的挑選最簡單的來處理就可以了,若是你的話,你會挑哪一個呢?
其實這跟經驗有些正相關,若是我遇到新聞這類的,我肯定直覺就會去找 rss。而拜 google news 所賜,我們要找這類的東西其實非常方便,可以去 https://news.google.com/news/?ned=zh-tw_tw&gl=TW&hl=zh-tw 這邊就統整了各家的新聞。
進到 google news 後,我們可以去選擇關鍵字,這邊就會出現所有 NBA 相關新聞。當然我們也可以針對這頁來去做爬取,但其實不用那麼累,因為下面就有 rss 可以使用。點開 rss,就有完整的 xml 可供使用,那我們只需要解析這部分就解決了。
要取得 NBA 新聞,會進行以下兩個步驟:
基本上就一個 get request,沒有什麼問題。另外我們觀察到,這個網址包含了我們所 query 的關鍵字,嘗試把關鍵字替換,也就能夠搜尋出不同的主題。
因為是 xml,所以等下我們實作的時候要有一個 xml parser,然後對每一個 item,就能取得最新新聞了。
我們先來撰寫取得 RSS 的 function,收一個 query string,然後將查詢到的 xml 轉成 js object,我們這邊使用 xml-js 來解析,最後將 items 整理後丟給 callback 就可以了。
function getNews(query, callback){
request(`https://news.google.com/news/rss/search/section/q/${query}/?hl=zh-tw&gl=TW&ned=zh-tw_tw`, (err, res, body)=>{
var items = convert.xml2js(body, {compact: true}).rss.channel.item
items = items.map((news)=>{
return {
title: news.title._text,
link: news.link._text,
time: news.pubDate._text,
}
})
callback(items)
})
}
const request = require('request');
const convert = require('xml-js');
getNews('nba', (news)=>{
console.log(news);
})
function getNews(query, callback){
request(`https://news.google.com/news/rss/search/section/q/${query}/?hl=zh-tw&gl=TW&ned=zh-tw_tw`, (err, res, body)=>{
var items = convert.xml2js(body, {compact: true}).rss.channel.item
items = items.map((news)=>{
return {
title: news.title._text,
link: news.link._text,
time: news.pubDate._text,
}
})
callback(items)
})
}
這也是一個很經典的案例,若你無法掌握最簡易的資料來源,那麼你可能會大費周章的去爬取網站,解析 request,而選對資料來源,就會非常容易。
爬取新聞這類的需求,其實除了博弈類以外,我至少遇過四、五次,有一個比較特別的是我自己的需求,我自己有在玩地下論壇,而該論壇有強制論壇會員每隔一段時間必須分享或發文,所以我自己就寫了一隻爬蟲,每隔一段時間就去自動抓取新聞,然後自動貼到新聞區,一勞永逸。爬蟲技術其實不難,有趣的是看你怎麼玩。