首頁  >  文章  >  web前端  >  多頁面爬蟲在nodejs中的範例程式碼分析

多頁面爬蟲在nodejs中的範例程式碼分析

黄舟
黄舟原創
2017-05-31 10:11:271598瀏覽

這篇文章主要介紹了基於nodejs 的多頁爬蟲 ,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟著小編過來看看吧

前言

前端時間再回顧了一下node.js,於是順勢做了一個爬蟲來加深自己對node的理解。

主要用的到是request,cheerio,async三個模組

#request

用於請求位址和快速下載圖片串流。

cheerio

為伺服器特別客製化的,快速、靈活、實作的jQuery核心實作.

方便解析html程式碼。 

async

非同步調用,防止阻塞。

核心思路

  1. 用request 傳送一個請求。取得html程式碼,取得其中的img標籤和a標籤。

  2. 透過取得的a表情進行遞歸呼叫。不斷取得img位址和a位址,繼續遞歸

  3. 取得img位址透過request(photo).pipe(fs.createWriteStream(dir + “/” + filename));進行快速下載。

function requestall(url) {

 request({

  uri: url,

  headers: setting.header

 }, function (error, response, body) {

  if (error) {

   console.log(error);

  } else {

   console.log(response.statusCode);

   if (!error && response.statusCode == 200) {

    var $ = cheerio.load(body);

    var photos = [];

    $('img').each(function () {

     // 判断地址是否存在

     if ($(this).attr('src')) {

      var src = $(this).attr('src');

      var end = src.substr(-4, 4).toLowerCase();

      if (end == '.jpg' || end == '.png' || end == '.jpeg') {

       if (IsURL(src)) {

        photos.push(src);

       }

      }

     }

    });

    downloadImg(photos, dir, setting.download_v);

    // 递归爬虫

    $('a').each(function () {

     var murl = $(this).attr('href');

     if (IsURL(murl)) {

      setTimeout(function () {

       fetchre(murl);

      }, timeout);

      timeout += setting.ajax_timeout;

     } else {

      setTimeout(function () {

       fetchre("http://www.ivsky.com/" + murl);

      }, timeout);

      timeout += setting.ajax_timeout;

     }

    })

   }

  }

 });

}

防坑

1.在request透過圖片位址下載時,綁定error事件防止爬蟲異常的中斷。

2.透過async的mapLimit限制並發。

3.加入請求報頭,防止ip被封鎖。

4.取得一些圖片和超連結位址,可能是相對路徑(待考慮解決是否有通過方法)。

function downloadImg(photos, dir, asyncNum) {

 console.log("即将异步并发下载图片,当前并发数为:" + asyncNum);

 async.mapLimit(photos, asyncNum, function (photo, callback) {

  var filename = (new Date().getTime()) + photo.substr(-4, 4);

  if (filename) {

   console.log('正在下载' + photo);

   // 默认

   // fs.createWriteStream(dir + "/" + filename)

   // 防止pipe错误

   request(photo)

    .on('error', function (err) {

     console.log(err);

    })

    .pipe(fs.createWriteStream(dir + "/" + filename));

   console.log('下载完成');

   callback(null, filename);

  }

 }, function (err, result) {

  if (err) {

   console.log(err);

  } else {

   console.log(" all right ! ");

   console.log(result);

  }

 })

}

測試:


#可以感覺到速度還是比較快的。

 

#

以上是多頁面爬蟲在nodejs中的範例程式碼分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn