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 %' ;
}
執行結果如下