這裡介紹如何使用 Node.js 撰寫自動抓取網頁資料的程式,從網路上自動擷取大量的數據或資料。

在網頁 API 尚未風行的年代裡,如果想要從網路上自動取得一些資料,通常都只能從一般的網頁中擷取(web scraping),縱使現在許多網路上的資料都會提供程式專用的 API,但若遇到沒有提供完整功能 API 的網站,還是只能靠這個最基本的方式處理。

在過去有許多的工具或函式庫可以處理這些問題,而目前很熱門的 Node.js 同樣也可以達到這樣的效果,以下是使用 Node.js 撰寫網頁擷取程式的教學。


這裡我們會使用到的工具有:

  • Node.js:基本的 Node.js 環境。
  • Request:處理 HTTP 請求的 Node 套件。
  • cheerio:適用於伺服器端的 jQuery,可幫助我們擷取網頁中的資料。

抓取的網頁內容我們就以

http://www.wunderground.com/weather-forecast/zmw:00000.1.59358

這個 Weather Underground 所提供的台南市天氣資料做示範,抓取網頁上的氣溫與溼度這兩個數值。

Step 1
首先打開網頁的原始碼,找到氣溫的那一段 HTML 碼,大約會像這樣:

<span class="wx-data" data-station="I1318" data-variable="temperature">
  <span class="wx-value">35.9</span>
  <span class="wx-unit">°C</span>
</span>

由於它的程式碼結構非常漂亮,我們只要抓到有 data-variable="temperature" 的元素,再向下抓一個 class 是 wx-value 的元素,就可以獲得氣溫的數值了,而溼度的部分也是一樣用這樣的方式抓取。

確定網頁的結構與抓取資料的規則之後,就可以開始準備寫程式了。

Step 2
準備開發用的環境,安裝好 Node.js 之後,建立一個放置專案用的目錄:

mkdir myscraper

npm 自動安裝需要的套件:

cd myscraper
npm install request cheerio

Step 3
使用 requestcheerio 撰寫網頁擷取的指令稿,並將這個指令稿儲存成 scraper.js

var request = require("request");
var cheerio = require("cheerio");

// 台南市的氣溫
var url = "http://www.wunderground.com/weather-forecast/zmw:00000.1.59358";

// 取得網頁資料
request(url, function (error, response, body) {
  if (!error) {

    // 用 cheerio 解析 html 資料
    var $ = cheerio.load(body);

    // 篩選有興趣的資料
    var temperature = $("[data-variable='temperature'] .wx-value").html();
    var humidity = $("[data-variable='humidity'] .wx-value").html();

    // 輸出
    console.log("氣溫:攝氏 " + temperature + " 度");
    console.log("濕度:" + humidity + "%");

  } else {
    console.log("擷取錯誤:" + error);
  }
});

程式的整個流程很簡單,一開始用 request 將整張網頁抓回來,再將網頁的 HTML 原始碼交給 cheerio 解析,接著使用 jQuery 的語法,依照之前研究好的資料抓取規則,把對應的資料抓出來,最後是輸出。

Step 4
在命令列執行:

node scraper.js

輸出為:

氣溫:攝氏 35.4 度
濕度:49%

這裡因為只是示範教學,所以只有抓氣溫與溼度兩個數值而已,比較好的做法是連同數值的單位也一起抓取,這樣資料比較不容易出問題。

參考資料:Smashing Magazinescotch.ioDigital OceanMax Ogden