Chapter 7 - 簡單地爬蟲

Step1 : 安裝所需套件

npm install request cheerio

相關模組介紹:

request : 是一個用來簡化 HTTP 請求的模組

cheerio : 是一個JQuery Core的子集,處理了瀏覽器的 DOM 操作

Step2:匯入套件

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

Step2-1:使用request模組取得網頁內容

// 透過 GET 請求讀取

request('http://www.cwb.gov.tw/V7/forecast/taiwan/Taipei_City.htm',function(err,res,body){

    if(!error && res.statusCode == 200){
        // 輸出網頁內容
        console.log(body);
    }
});

Step2-2:使用cheerio取的網頁的資料

使用 css selector 擷取網頁的資料

var $ = cheerio.load(<h2 class="title">Hello World </h2>");
console.log($(h2.title).text()); // 輸出 Hello World

現在我們來氣象局來抓取天氣的相關資料當作練習吧!!

Step3 先觀察網頁結構:

發現我們要擷取的網頁資料位於 table 這個tag中,而他的class名稱是 FcstBoxTable01,於是乎我們透過程式去抓取這個 table 裡的資料

request('http://www.cwb.gov.tw/V7/forecast/taiwan/Taipei_City.htm',function(err,res,body){

    if(err){
        return console.log(err);
    }

    if(!err && res.statusCode == 200){

        //透過 load 方法把 HTML 轉換成 JQuery 物件
        var $ = cheerio.load(body);

        var weather = [];

        // 搜尋此 table 下的所有 tr
        $('.FcstBoxTable01 tbody tr').each(function(index,element){
            weather.push($(this).text());
        });

        console.log(weather);
    }
});

執行 crawler.js 查看目前結果為

node crawler

到目前為止,你發現了這邊所輸出的結果充滿了 tab 以及斷行符號,我們接下來將此切割以及取代掉吧,畢竟這些符號我們並不需要。

Step4: 依斷行符號來進行切割

request('http://www.cwb.gov.tw/V7/forecast/taiwan/Taipei_City.htm',function(err,res,body){

    if(err){
        return console.log(err);
    }

    if(!err && res.statusCode == 200){

        //透過 load 方法把 HTML 轉換成 JQuery 物件
        var $ = cheerio.load(body);

        var weather = [];

        // 搜尋此 table 下的所有 tr
        $('.FcstBoxTable01 tbody tr').each(function(index,element){
            weather.push($(this).text().split('\n'));
        });

        console.log(weather);
    }
});

目前結果:

到目前為止,發現了斷行符號已被我們切割掉了,然而目前還有 \t ,接下來將會一一的讀取 weather 陣列中的資料,將 \t 取帶掉

Step 5: 取代 \t

request('http://www.cwb.gov.tw/V7/forecast/taiwan/Taipei_City.htm',function(err,res,body){

    if(err){
        return console.log(err);
    }
    if(!err && res.statusCode == 200){

        //透過 load 方法把 HTML 轉換成 JQuery 物件
        var $ = cheerio.load(body);

        var weather = [];

        // 搜尋此 table 下的所有 tr
        $('.FcstBoxTable01 tbody tr').each(function(index,element){
            weather.push($(this).text().split('\n'));
        });

        var output = [];
        for(var index = 0 ; index < weather.length ; index++){
            output.push({
                time:weather[index][1].replace(/\t/g,'').split(' ')[0],
                tempartue:weather[index][2].replace(/\t/g,''),
                rain_probability:weather[index][6].replace(/\t/g,'')
            });
        }

        console.log(output);
    }
});

此時進執行程式的時候,有可能會出錯,因為你所抓取的欄位可能沒有資料,因此就會噴錯了,那要如何處理呢?我們在這邊會將欄位為 undefined or null 的資料設定為 0

Step6 :設定一個 function 去判斷每一個欄位的資料

function isEmptyOrUndefined(value){
    if(value === '' || typeof value != 'undefined'){
        value = value.replace(/\t/g,'');
        if(value != ''){
            return value;
        }
        return '0 %';
    }
    return '0 %' ;
}

完整程式碼如下:

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

request('http://www.cwb.gov.tw/V7/forecast/taiwan/Taipei_City.htm',function(err,res,body){

    if(err){
        return console.log(err);
    }


    //透過 load 方法把 HTML 轉換成 JQuery 物件
    var $ = cheerio.load(body);
    var weather = [];

    // 搜尋此 table 下的所有 tr
    $('.FcstBoxTable01 tbody tr').each(function(index,element){
        weather.push($(this).text().split('\n'));
    });

    var output = [];
    for(var index = 0 ; index <  weather.length; index ++){
        // global search in string
        output.push({
            time:weather[index][1].replace(/\t/g,'').split(' ')[0],
            tempartue: weather[index][2].replace(/\t/g,''),
            rain_probability : isEmptyOrUndefined(weather[index][6])
        });
    }
   console.log(output);
});
function isEmptyOrUndefined(value){
    if(value === '' || typeof value != 'undefined'){
        value = value.replace(/\t/g,'');
        if(value != ''){
            return value;
        }
        return '0 %';
    }
    return '0 %' ;
}

執行結果如下

results matching ""

    No results matching ""