node.js學習筆記(3)——使用cheerio處理爬取的網頁內容
一、簡介
node.js本身自帶爬取網站網頁內容的功能。
var http = require('http'); router.get('/test', function(req, res){ var url = 'http://www.baidu.com'; http.get(url, function(response){ var html = ''; response.on('data', function(data){ html += data; }); response.on('end', function(){ res.render('test', { 'html':html }); }) }) })
比如如上程式碼就實現了爬取baidu.com網頁程式碼內容,使用res.render直接將資料渲染到ejs模板中後的內容如下:
基本和原始碼一樣,非常難以手工處理。這就是為什麼我們需要cheerio模組來對爬取到的內容進行處理
二、cheerio
使用方式比較簡單:
1. 使用npm install安裝cheerio模組並新增到依賴中
2. 在js檔案中通過var cheerio = require('cheerio'); 獲取模組引用
3. var $ = cheerio.load(html,{decodeEntities:false});
(1)可以建立一個和jQuery選擇器用法差不多的選擇器 $.
(2)load函式的第一個引數html就是之前http.get方法中所獲得的資料;第二個引數可選,主要是用來設定格式,比如decodeEntities:false設定了不會出現中文亂碼。
三、簡單實戰
案例:爬取北京新發地市場的菜價內容。
1. 翻一下原始碼,檢視所需要的內容的類或者名字
2. 編寫程式碼
router.get('/test', function(req, res){ var url = 'http://www.xinfadi.com.cn/'; http.get(url, function(response){ var html = ''; response.on('data', function(data){ html += data; }); response.on('end', function(){ var $ = cheerio.load(html,{decodeEntities:false}); var content = $('.conLi').text(); res.render('test', { 'html':content }); }) }) })
然後就會出現如下的內容:
3. cheerio的用法完全可以和寫css樣式一樣,通過多個類、名等方式選擇。
比如可以這樣寫:var content = $('#tab1_div_0 .conLi em').text();
然後就會出現更為細緻的效果
4. 一點嘗試
看到cheerio提供了toArray方法,對於li, em這樣的元素,可以轉換為陣列。嘗試一下後結果
陣列是物件型別的,而且由於物件中包含了對自身的引用,使用JSON.stringify方法不能夠將物件以字串形式輸出。必須引入util模組,用util.inspect()方法對物件進行轉換。隨便轉換一下後發現內容是這樣的:
知道了結構之後按照結構去找資料,最後效果如下:(如果想去掉引號的話使用replace方法加正則表示式即可)
前端表格ejs程式碼:(使用了前端框架bootstrap)
<div class="container">
<table class="table table-bordered">
<thead>
<tr>
<th colspan="<%= list.length %>" class="table-title">蔬菜表</th>
</tr>
</thead>
<tbody>
<tr class="success">
<% for(var i=0; i<cols; i++) { %>
<td><%= list[i].toString() %></td>
<% } %>
</tr>
<% var counter = 0; %>
<% while(counter < content.length) { %>
<tr>
<% for(var i=0; i<list.length; i++) { %>
<td><%= content[i+counter] %></td>
<% } %>
<% counter = counter + list.length %>
</tr>
<% } %>
</tbody>
</table>
</div>
後端程式碼:(部分)
response.on('end', function(){
var $ = cheerio.load(html,{decodeEntities:false});
var list = $('.tabLi em').toArray();
var content = $('#tab1_div_0 .conLi em').toArray();
var list2 = new Array();
for(var i=0; i<list.length; i++){
list2[i] = util.inspect(list[i].children[0].data);
}
var content2 = new Array();
for(var i=0; i<content.length; i++){
content2[i] = util.inspect(content[i].children[0].data);
}
res.render('test', {
'list':list2,
'cols':list.length,
'content':content2,
});
})
四、總結
爬取網站內容的精髓(不考慮面對反爬取機制的處理)的在於分析,分析它的結構並貼身打造、對症下藥。
五、附贈:url中出現中文的問題
在新發地網站進行商品的檢索時,發現url中有中文
使用 encodeURI(name) 方法可以實現將中文字串編碼。