iT邦幫忙

2021 iThome 鐵人賽

DAY 9
1
Modern Web

JavaScript Easy Go!系列 第 9

#9 Web Crawler 2

We are going to start coding!!

想法

這個爬蟲的想法很簡單,對於每個 Block,我們從第一個 Page 開始爬,直到最後一個。

對,就醬。

在這裡,我們只需要處理一個問題:如何判定最後一頁到了沒?

我們的方法是:用「視覺」上的差異決定,因為網站本來就是做給人看的,所以爬蟲最好也依人的「視角」去爬。

當你在看鐵人賽文章列表時,從哪裡可以看出這一頁是不是最後一頁?

沒錯,就是下面這條:

在這條頁數條上,有兩項能拿來當指標的東西:「當前頁面標示」及「下一頁按鈕狀態」。
在這裡,我們選擇以「當前頁面標示」作為判定已經是最後一頁的指標

當我們在最後一頁時,「當前頁面標示」是沒有下一項的:
按鈕不能用QQ

好了,想法的部分大概都結束了,接下來來寫程式吧!

建立專案

相信各位都裝了 Node.js 了吧?
現在讓我們建立一個專案的資料夾,取你喜歡的名稱即可,我自己取 iT_Crawler

然後至該資料夾內執行:

npm init -y

它就會自動建立好這個檔案了:

接著安裝需要的 Packages:

npm i node-fetch@2 jsdom

我們使用 node-fetch 來發送請求,接著用 jsdom 來解析
使用 node-fetch@2 的原因是因為 node-fetch@3 只支援 esm,要用還得改 package.json

然後我們建立 index.js

專案建立完成!

撰寫程式

程式都寫在 index.js 裡喔。

引入 Packages

先引入我們需要的 Packages,等等就可以在程式中用了。

const fs = require("fs");
const fetch = require("node-fetch");
const { JSDOM } = require("jsdom");

疑?我們剛剛沒有安裝 fs 這個 Package 啊,為什麼可以引用?
因為 fs 是 Node.js 內建的 Package,用來操作檔案系統。

定義 main 函式

async function main() {
    // 紀錄程式開始時間
    const START_TIME = new Date();

    // 定義 iThelp 鐵人賽網址及 Block 名稱
    const baseURL = "https://ithelp.ithome.com.tw/2021ironman/";
    const types = ["contest", "self"];

    // 爬取資料
    const results = await Promise.all(types.map((type) => crawler(baseURL + type)));
    // 整理資料,降維及排序
    const data = results.reduce((a, b) => a.concat(b), []);
    data.sort((a, b) => b.view - a.view || b.date[1] - a.date[1] || b.date[2] - a.date[2]);

    // 儲存資料
    saveData(data);

    // 紀錄程式結束時間
    const END_TIME = new Date();
    // 計算程式執行時間
    console.log(`Crawled ${data.length} Articles in ${((END_TIME - START_TIME) / 1000).toFixed(2)}s`);
}

之後執行時,我們的程式從 main 開始執行。
你可能會覺得奇怪, JavaScript 不需要定義 main 函式啊?
沒錯,但因為我們會用到 await 所以為了避免在 Top Level 用發生問題,我們就把主程式也寫成一個函式 main,然後再執行它。

我們希望 main 會有幾個功能:

  • 爬取資料
  • 整理資料
  • 儲存資料
  • 記錄用時

相關程式碼就如上方所示,程式碼也幾乎逐行用註解標示功能了,應該非常明瞭。
接著,我們只要再寫 crawler 函式及 saveData 函式就好了。
就期待明天吧!


每日鐵人賽熱門 Top 10 (0922)

以 9/22 20:00 ~ 9/23 20:00 文章觀看數增加值排名

  1. +845 Day 1 無限手套 AWS 版:掌控一切的 5 + 1 雲端必學主題
    • 作者: 用圖片高效學程式
    • 系列:無限手套 AWS 版:掌控一切的 5 + 1 雲端必學主題
  2. +678 Day 2 AWS 是什麼?又為何企業這麼需要 AWS 人才?
    • 作者: 用圖片高效學程式
    • 系列:無限手套 AWS 版:掌控一切的 5 + 1 雲端必學主題
  3. +668 Day 3 雲端四大平台比較:AWS . GCP . Azure . Alibaba
    • 作者: 用圖片高效學程式
    • 系列:無限手套 AWS 版:掌控一切的 5 + 1 雲端必學主題
  4. +625 Day 4 網路寶石:AWS VPC Region/AZ vs VPC/Subnet 關係介紹
    • 作者: 用圖片高效學程式
    • 系列:無限手套 AWS 版:掌控一切的 5 + 1 雲端必學主題
  5. +619 Day 5 網路寶石:AWS VPC 架構 Routes & Security (上)
    • 作者: 用圖片高效學程式
    • 系列:無限手套 AWS 版:掌控一切的 5 + 1 雲端必學主題
  6. +606 Day 7 網路寶石:【Lab】VPC外網 Public Subnet to the Internet (IGW) (上)
    • 作者: 用圖片高效學程式
    • 系列:無限手套 AWS 版:掌控一切的 5 + 1 雲端必學主題
  7. +604 Day 6 網路寶石:AWS VPC 架構 Routes & Security (下)
    • 作者: 用圖片高效學程式
    • 系列:無限手套 AWS 版:掌控一切的 5 + 1 雲端必學主題
  8. +570 Day 8 網路寶石:【Lab】VPC外網 Public Subnet to the Internet (IGW) (下)
    • 作者: 用圖片高效學程式
    • 系列:無限手套 AWS 版:掌控一切的 5 + 1 雲端必學主題
  9. +569 Day 18 儲存寶石:【Lab】S3 儲存類別 & 生命週期管理 (下)
    • 作者: 用圖片高效學程式
    • 系列:無限手套 AWS 版:掌控一切的 5 + 1 雲端必學主題
  10. +568 Day 9 運算寶石:EC2 重點架構
    • 作者: 用圖片高效學程式
    • 系列:無限手套 AWS 版:掌控一切的 5 + 1 雲端必學主題

今天中午 iThelp 被炸了(?) 所以沒有 12:00 的資料 QQ,只好用 20:00 來代替。


上一篇
#8 Web Crawler 1
下一篇
#10 Web Crawler 3
系列文
JavaScript Easy Go!31

尚未有邦友留言

立即登入留言