node.js 爬蟲入門總結

node.js爬蟲

前端同窗可能向來對爬蟲不是很感冒,以爲爬蟲須要用偏後端的語言,諸如 php , python 等。固然這是在 nodejs 前了,nodejs 的出現,使得 Javascript 也能夠用來寫爬蟲了。因爲 nodejs 強大的異步特性,讓咱們能夠輕鬆以異步高併發去爬取網站,固然這裏的輕鬆指的是 cpu 的開銷。php

要讀懂本文,其實只須要有

  • 能看懂 Javascript 及 JQuery
  • 簡單的nodejs基礎
  • http 網絡抓包 和 URL 基礎

Nodejs作爬蟲的優劣

首先說一下node作爬蟲的優點

第一個就是他的驅動語言是JavaScript。JavaScript在nodejs誕生以前是運行在瀏覽器上的腳本語言,其優點就是對網頁上的dom元素進行操做,在網頁操做上這是別的語言沒法比擬的。html

第二就是nodejs是單線程異步的。聽起來很奇怪,單線程怎麼可以異步呢?想一下學操做系統的時候,單核cpu爲何可以進行多任務處理?道理也是相似,在操做系統中進程對CPU的佔有進行時間切片,每個進程佔有的時間很短,可是全部進程循環不少次,所以看起就像是多個任務在同時處理。js也是同樣,js裏有事件池,CPU會在事件池循環處理已經響應的事件,未處理完的事件不會放到事件池裏,所以不會阻塞後續的操做。在爬蟲上這樣的優點就是在併發爬取頁面上,一個頁面未返回不會阻塞後面的頁面繼續加載,要作到這個不用像python那樣須要多線程。前端

其次是node的劣勢

首先是異步併發上。處理的好很方便,處理的很差就會很麻煩。例如要爬取10個頁面,用node不作異步處理話,那返回的結果可不必定是按一、二、三、4……這個順序,極可能是隨機。解決的辦法就是增長一個頁面的序列戳,讓爬取的數據生成csv文件,而後從新排序。node

第二個是數據處理上的劣勢,這點是不如python的,若是隻是單純的爬數據,用node固然很好,可是若是用爬來的數據繼續作統計分析,作個迴歸分析聚類啥的話,那就不能用node一步到底了。python

如何用nodejs作爬蟲

下面就要說一下如何用nodejs作爬蟲了

  • 一、初始化項目文件

在對應的項目文件夾下執行npm init來初始化一個package.json文件jquery

  • 二、安裝request和cheerio依賴包

request聽起來很熟悉吧,跟python裏request功能同樣。它的功能就是創建起對目標網頁的連接,並返回相應的數據,這個不難理解。程序員

cheerio的功能是用來操做dom元素的,他能夠把request返回來的數據轉換成可供dom操做的數據,更重要的cheerio的api跟jquery同樣,用$來選取對應的dom結點,是不很方便?對一個前端程序員來講,這比python的什麼xpath和beautisoup方便了不知道多少啊哈哈npm

安裝命令也很簡單:json

分別是npm install request --save 和 npm install cheerio後端

  • 三、引入依賴包並使用

接下來就用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爬蟲的核心就已經介紹完畢了,剩下就徹底能夠自由發揮了

相關文章
相關標籤/搜索