今天終於要開始寫點有用的東西了:網路爬蟲。
這次我們就來爬鐵人賽的文章吧。
在做爬蟲的第一個步驟是要先設定我們想要得到的資料的結構,這很大程度影響之後拿到一堆資料後的分析程序。
不過,這次我們的目標就是做出每天文章下面那塊「每日鐵人賽熱門 Top 10」,所以結構不會太複雜,只需要平面的存同時間切面的所有文章就行。
// 數據結構
Data = {
"09/21": [article1, article2, ...], // n 天抓的資料
"09/22": [article1, article2, ...] // n+1 天抓的資料
}
在做爬蟲的第二個步驟則是要瞭解目標網站的結構,因為這會涉及到爬蟲要怎麼寫。
我們可以從鐵人賽文章頁面看到他有分「主題競賽」、「技術推廣專區」及「自我挑戰組」三大區塊,但其實「技術推廣專區」的文章都包含在「主題競賽」內了,所以在爬的時候不需要處理「技術推廣專區」。
我們估且把那些區塊稱為 Block
。
在每個 Block
內呢,我們都可以看到有一個文章的列表,當然,他們被分成很多頁,少則 200 ~ 300,多則 500 ~ 600,我們稱它為 Page
,而每個 Page
內又有許多 Article
。
因為分頁的緣故,網站上的數據結構與我們所希望的數據結構有些不同:
// 網站上的數據結構
Data = {
"Block1": {
"Pages": [
{
"Articles": [article1, article2, ...]
}
]
},
"Block2": {
"Pages": [
{
"Articles": [article1, article2, ...]
}
]
}
}
我們會希望把它變成:
// 目標數據結構
Data = [article1, article2, ...];
隨著時間的增長,我們可以知道 Page
數會增加,但 Block
數是固定的,所以在這裡我們 hard code Block
不會有什麼大問題,但對 Page
和 Article
就不能這樣了。為什麼 Article
也不行?因為我們不確定最後一個 Page
會剩多少文章。
再來,我們得先想想爬蟲可能會遇到的問題,以及應對方案。
這個問題會發生的原因是因為爬蟲在爬取時是需要時間的,並不是在一個瞬間掃過所有頁面,而是一步一步的爬,所以如果當我們在爬的時候有人發表一則新文章,那整個列表就會被推移而重複爬取一則文章或遺失一則文章,取決於爬取方向。
這個問題的處理方法算是蠻簡單的,當遺漏文章時,我們自己是不會知道的,頂多發現總文章數與我們爬到的不符,但無法以已爬取資料得到少了哪個文章的資訊,所以我們選擇接受「重複」而非「遺漏」,因為重複文章較容易找出,只需要用 Map
之類唯一鍵值的資料結構就好。
如果你想用「瞬間掃過所有頁面」的方式根本性的解決這個問題,請先想想:
- 你的網路頻寬夠嗎?
- 伺服器的網路頻寬夠嗎?
- 道德嗎?會不會被當成 DDOS?
這個問題可就複雜了,可能是我們自己的網路問題、伺服端的網絡問題、解析發生錯誤或不明原因。
處理方法就...設定重試規則吧。
一定會有在初始階段沒想到的問題在之後浮現,這時候只能把寫好的程式改掉修正問題或忽略它,所以最好還是能先想到,避免白花力氣。
所以你要一定要記得裝 Node.js。
以 9/21 12:00 ~ 9/22 12:00 文章觀看數增加值排名
+330
Day 2:什麼是 SRE
+209
[Day 03] tinyML開發板介紹
+192
深入淺出 Computed
+183
06 APCS 考試內容 Overview
+161
#1 JavaScript Easy Go!
+157
#4 Array & Object in JavaScript
+157
#6 JavaScript & Node.js
+151
07 Re: 從零開始的競程生活
+139
Angular 深入淺出三十天:表單與測試 Day06 - 單元測試實作 - 登入系統 by Template Driven Forms
+130
05 - Uptime - 掌握系統的生命徵象 (3/3) - 透過 Kibana 觀看心電圖及設定警報
恭喜 bogay 學長封頂