node.js爬蟲
前端同學可能向來對爬蟲不是很感冒,覺得爬蟲需要用偏后端的語言,諸如 php , python 等。當然這是在 nodejs 前了,nodejs 的出現,使得 Javascript 也可以用來寫爬蟲了。由于 nodejs 強大的異步特性,讓我們可以輕松以異步高并發去爬取網站,當然這里的輕松指的是 cpu 的開銷。
要讀懂本文,其實只需要有
- 能看懂 Javascript 及 JQuery
- 簡單的nodejs基礎
- http 網絡抓包 和 URL 基礎
Nodejs做爬蟲的優劣
首先說一下node做爬蟲的優勢
第一個就是他的驅動語言是JavaScript。JavaScript在nodejs誕生之前是運行在瀏覽器上的腳本語言,其優勢就是對網頁上的dom元素進行操作,在網頁操作上這是別的語言無法比擬的。
第二就是nodejs是單線程異步的。聽起來很奇怪,單線程怎么能夠異步呢?想一下學操作系統的時候,單核cpu為什么能夠進行多任務處理?道理也是類似,在操作系統中進程對CPU的占有進行時間切片,每一個進程占有的時間很短,但是所有進程循環很多次,因此看起就像是多個任務在同時處理。js也是一樣,js里有事件池,CPU會在事件池循環處理已經響應的事件,未處理完的事件不會放到事件池里,因此不會阻塞后續的操作。在爬蟲上這樣的優勢就是在并發爬取頁面上,一個頁面未返回不會阻塞后面的頁面繼續加載,要做到這個不用像python那樣需要多線程。
其次是node的劣勢
首先是異步并發上。處理的好很方便,處理的不好就會很麻煩。例如要爬取10個頁面,用node不做異步處理話,那返回的結果可不一定是按1、2、3、4……這個順序,很可能是隨機。解決的辦法就是增加一個頁面的序列戳,讓爬取的數據生成csv文件,然后重新排序。
第二個是數據處理上的劣勢,這點是不如python的,如果只是單純的爬數據,用node當然很好,但是如果用爬來的數據繼續做統計分析,做個回歸分析聚類啥的話,那就不能用node一步到底了。
如何用nodejs做爬蟲
下面就要說一下如何用nodejs做爬蟲了
- 1、初始化項目文件
在對應的項目文件夾下執行npm init來初始化一個package.json文件
- 2、安裝request和cheerio依賴包
request聽起來很熟悉吧,跟python里request功能一樣。它的功能就是建立起對目標網頁的鏈接,并返回相應的數據,這個不難理解。
cheerio的功能是用來操作dom元素的,他可以把request返回來的數據轉換成可供dom操作的數據,更重要的cheerio的api跟jquery一樣,用$來選取對應的dom結點,是不很方便?對一個前端程序員來說,這比python的什么xpath和beautisoup方便了不知道多少啊哈哈
安裝命令也很簡單:
分別是npm install request --save 和 npm install cheerio
- 3、引入依賴包并使用
接下來就用request , fs和cherrio寫一個爬蟲吧!
首先引入依賴模塊
var http=require("http"); //網絡請求var fs=require("fs"); //操作文件,讀寫文件var cheerio=require("cheerio"); //擴展模塊注:cheerio 模塊是第三方模塊,需要進行安裝:npm install cheerio --save
接下來就以我之前爬取的的百度新聞頁為例吧,為什么要選這個呢,因為這個是最基礎最簡單的。
百度新聞頁面鏈接是:http://news.baidu.com/
執行下面代碼:
var http=require("http");
var fs=require("fs");const wz="http://news.baidu.com/"; //網址var strHtml="";
var results=[];
http.get(wz,function(res){res.on("data",function(chunk){strHtml+=chunk;})res.on("end",function(){console.log(strHtml);});
})
運行一下結果就是這樣的
是不是很激動哈哈,html返回回來了。這樣還是不夠的,接下就是要處理下返回的數據,并提煉出我們想要獲得的信息,這就輪到cheerio登場了
將request返回的結果傳入cheerio中,并獲得想要獲取的信息,看代碼是不是想在寫腳本的感覺?
接下來我們在獲取一下這一段
執行以下代碼:
var http=require("http");var fs=require("fs");var cheerio=require("cheerio");const wz="http://news.baidu.com/";var strHtml="";
var results=[];
http.get(wz,function(res){res.on("data",function(chunk){strHtml+=chunk;})res.on("end",function(){//console.log(strHtml);var $=cheerio.load(strHtml);$("#channel-all li").each((iten,i)=>{console.log($(i).text());})});
})
運行一下結果如下:
這樣一個簡單的爬蟲就完成啦,是不是很簡單啊。
然后再簡單的介紹一下node.js爬取圖片
以下是我們將要爬取的圖片:
首先我們也需要同上面一樣引入一些需要的核心模塊
var http = require("http");var https = require("https");var fs = require("fs");var cheerio = require("cheerio");
注:cheerio 模塊是第三方模塊,需要進行安裝:
npm install cheerio --save
//保存網絡圖片
function saveImage(imageUrl){http.get(imageUrl, function (res) {res.setEncoding('binary'); //二進制(binary)var imageData ='';res.on('data',function(data){ //圖片加載到內存變量imageData += data;}).on('end',function(){ //加載完畢保存圖片if(!fs.existsSync("./images")){fs.mkdirSync("./images");}fs.writeFile('images/'+Math.random()+'.png',imageData,'binary',function (err) { //以二進制格式保存if(err) throw err;console.log('保存成功');});});});
}
nodejs 爬蟲總結
① http.get+cheerio+iconv-lite
這種方式還是比較簡單的,容易理解,直接使用http的get方法進行請求url,將得到的內容給cheerio解析,用jquery的方式解析出我們要東西即可。
要點:
得到的結果中文亂碼如何解決呢,用iconv-lite模塊將得到的內容進行轉碼即可。
http.get(options,function(result){var body = [];result.on('data',function(chunk){body.push(chunk);});result.on('end', function () {var html = iconv.decode(Buffer.concat(body), 'gb2312'); //注意這里body是數組var $ = cheerio.load(html);...});
});
② request+cheerio+iconv-lite
這種方式在獲取內容的方式上與上有些不同,可以直接獲取到Buffer類型的數據。然后將得到的內容給cheerio解析,用jquery的方式解析出我們要東西即可。
要點:
結果中文亂碼如何解決,用iconv-lite模塊將得到的內容進行轉碼即可。
request(options,function(err,res,body){if(err)console.log(err);if(!err&&res.statusCode==200){var html = iconv.decode(body, 'gb2312'); //這里body是直接拿到的是Buffer類型的數據,可以直接解碼。var $ = cheerio.load(html);...}
});
③ superagent+cheerio+superagent-charset
這種方式是比前面兩個有較大差別,用了superagent的get方法發起請求,解碼的時候用到了superagent-charse,用法還是很簡單的,之后再將獲取到的內容給cheerio解析,用jquery的方式解析出我們要東西即可。
要點:
結果中文亂碼解決用superagent-charset模塊進行轉碼,方式較之上面有點差別。
首先看它的加載方式:
var charset = require("superagent-charset");var superagent = charset(require("superagent")); //將superagent模塊傳遞給superagent-charset
解碼方式:
superagent.get(url).charset('gb2312') //用charset方法達到解碼效果。.end(function(err,result){if(err) console.log(err);var $ = cheerio.load(result.text);...});
至此呢,Nodejs爬蟲的核心就已經介紹完畢了,剩下就完全可以自由發揮了