nodejs爬蟲項目實戰

這篇文章主要介紹了NodeJS製做爬蟲的全過程,包括項目創建,目標網站分析、使用superagent獲取源數據、使用cheerio解析、使用eventproxy來併發抓取每一個主題的內容等方面,有須要的小夥伴參考下吧。
html

1、 依賴

1. DOM操做 cheerio

2. 請求插件 request

3. http庫 superagent

4. 代理 eventproxy

2、創建項目node-spider

1. 創建一個Koa2項目

npm install -g koa-generatornode

2. 生成一個koa2的項目

koa2 -e node-spider -e表示使用ejs模板,具體參照koa生成器,一鍵生成koa和koa2項目ajax

3、目標網站分析

如圖,這是CNode首頁一部分div標籤,咱們就是經過這一系列的id、class來定位咱們須要的信息。
npm

4、爬蟲功能製做

1. superagent

是ajax API來使用的Http庫,它的使用方法與jQuery差很少,咱們經過它發起get請求,在回調函數中輸出結果。數組

var koa = require('koa');
  var router = require('koa-router')
  var url = require('url'); //解析操做url
  var superagent = require('superagent'); //這三個外部依賴不要忘記npm install
  var cheerio = require('cheerio');
  var eventproxy = require('eventproxy');
  var targetUrl = 'https://cnodejs.org/';
  superagent.get(targetUrl)
    .end(function (err, res) {
        console.log(res);
    });

它的res結果爲一個包含目標url信息的對象,網站內容主要在其text(string)裏。服務器

2. 使用cheerio解析

cheerio充當服務器端的jQuery功能,咱們先使用它的.load()來載入HTML,再經過CSS selector來篩選元素。併發

var $ = cheerio.load(res.text);
  //經過CSS selector來篩選數據
  $('#topic_list .topic_title').each(function (idx, element) {
      console.log(element);
  });

其結果爲一個個對象,調用 .each(function(index, element))函數來遍歷每個對象,返回的是HTML DOM Elements。koa

輸出 console.log($element.attr('title'));的結果爲
廣州2014年12月06日 NodeParty 之 UC 場之類的標題
輸出 console.log($element.attr('href'));的結果爲
/topic/545c395becbcb78265856eb2之類的url
再用NodeJS1的url.resolve()函數來補全完整的url。ide

superagent.get(tUrl)
    .end(function (err, res) {
        if (err) {
            return console.error(err);
        }
        var topicUrls = [];
        var $ = cheerio.load(res.text);
        // 獲取首頁全部的連接
        $('#topic_list .topic_title').each(function (idx, element) {
            var $element = $(element);
            var href = url.resolve(tUrl, $element.attr('href'));
            console.log(href);
            //topicUrls.push(href);
        });
    });

3.使用eventproxy來併發抓取

教程上展現了深度嵌套(串行)方法和計數器方法的例子,eventproxy就是使用事件(並行)方法來解決這個問題。當全部的抓取完成後,eventproxy接收到事件消息自動幫你調用處理函數。函數

//第一步:獲得一個 eventproxy 的實例
  var ep = new eventproxy();
  //第二步:定義監聽事件的回調函數。
  //after方法爲重複監聽
  //params: eventname(String) 事件名,times(Number) 監聽次數, callback 回調函數
  ep.after('topic_html', topicUrls.length, function(topics){
      // topics 是個數組,包含了 40 次 ep.emit('topic_html', pair) 中的那 40 個 pair
      //.map
      topics = topics.map(function(topicPair){
          //use cheerio
          var topicUrl = topicPair[0];
          var topicHtml = topicPair[1];
          var $ = cheerio.load(topicHtml);
          return ({
              title: $('.topic_full_title').text().trim(),
              href: topicUrl,
              comment1: $('.reply_content').eq(0).text().trim()
          });
      });
      //outcome
      console.log('outcome:');
      console.log(topics);
  });
  //第三步:肯定放出事件消息的
  topicUrls.forEach(function (topicUrl) {
      superagent.get(topicUrl)
          .end(function (err, res) {
              console.log('fetch ' + topicUrl + ' successful');
              ep.emit('topic_html', [topicUrl, res.text]);
          });
  });

結果以下

獲取留言用戶名和積分

在文章頁面的源碼找到評論的用戶class名,classname爲reply_author。console.log第一個元素 $('.reply_author').get(0)能夠看到,咱們須要獲取東西都在這裏頭。

首先,咱們先對一篇文章進行抓取,一次性把須要的都獲得便可。

var userHref = url.resolve(tUrl, $('.reply_author').get(0).attribs.href);
  console.log(userHref);
  console.log($('.reply_author').get(0).children[0].data);

咱們能夠經過https://cnodejs.org/user/username抓取積分信息

$('.reply_author').each(function (idx, element) {
var $element = $(element);
console.log($element.attr('href'));
});

在用戶信息頁面 $('.big').text().trim()即爲積分信息。
使用cheerio的函數.get(0)爲獲取第一個元素。

var userHref = url.resolve(tUrl, $('.reply_author').get(0).attribs.href);
console.log(userHref);
相關文章
相關標籤/搜索