借助Nodejs在服務端使用jQuery采集17173游戲排行信息


Nodejs相關依賴模塊介紹

Nodejs的優勢這里就不做介紹啦,這年頭相信大家對它也不陌生了。這里主要介紹一下用到的第三方模塊。

  • async:js代碼中到處都是異步回調,很多時候我們需要做同步處理,使用async可以大大簡化我們的同步處理的任務(沒有它的時候,可能要用遞歸去處理異步問題了)。
  • jsdom:一個 W3C DOM 的 JS 實現。用這玩意相當犀利,它不僅可以將文檔解析成 DOM,而且,你還可以用 YUI 或着 jQuery 去操作生成的 DOM。這在從頁面中提取數據時格外有用。這次采集17173的游戲排行數據就是用它結合jQuery去做的。
  • colors:這個主要是便於我們從終端中輸出不同顏色的信息用的,它的用法相當簡單,console.log的時候直接在字符串后附加相關的顏色信息就可以了。

17173游戲排行頁面分析

17173游戲排行頁面:http://top.17173.com/index-0-0-0-0-0-0-0.html

我們要抓取它的排行,游戲名,熱度值和測試狀態信息,為了保存方便,直接將抓取的這些信息以CSV格式文件保存。

排行信息總共有63頁,使用Chrome調試發現,請求不同頁的數據時,發送的是HTTP POST請求,不同的頁數通過page參數傳遞的,參數t可以忽略,主要是清瀏覽器緩存用的,如下圖所示:

 使用Chrome查看html結構,我們要抓取的數據在ul.ph-bd-list li中,如下圖所示:

在前端獲取游戲排行列表的Html信息時,使用jQuery,$('.ph-bd-list li')可以非常方便的定位到列表信息,如果在服務端也能使用這種方式提取信息豈不爽哉,如下圖所示:

Nodejs在服務端使用jQuery采集游戲排行信息

首先要解決的問題是,如何使用nodejs發送post請求,並從服務器返回的信息中得到html。

完成這件事並不難,查看一下nodejs,http模塊相關的文檔,文檔中剛好有個示例,幾乎可以直接拿來用,需要注意的是,nodejs接收服務端返回的數據時,是以數據塊的形式接收的,我們需要將這些數據塊,拼裝成完整的數據,代碼如下:

// 構造請求信息
var options = {
  hostname: 'top.17173.com',
  port: 80,
  path: '/index-0-0-0-0-0-0-0.html?page=' + index,
  method: 'POST'
};

var req = http.request(options, function(res) {
  var html = '';
  res.setEncoding('utf8');
  // 拼裝數據
  res.on('data', function (chunk) { html += chunk; });
  res.on('end', function () {
    parseHtml(html, callback);  // 對html做解析處理
  });
});

req.on('error', function(e) {
  console.log(('請求列表頁失敗: ' + e.message).red);
});

// write data to request body
req.write('data\n');
req.write('data\n');
req.end();

接下來需要對html做處理,我們需要用jsdom將html解析為DOM,並跟jQuery結合,確保在服務端能夠使用jQuery操作DOM,為了便於使用,我把這些操作做了簡單的封裝,核心代碼如下:

var jsdom = require('jsdom').jsdom
  , fs = require('fs')
  , jquery = fs.readFileSync("./jquery.js", "utf-8");

/**
 * 使用jsdom將html跟jquery組裝成dom
 * @param  {[type]}   html     需要處理的html
 * @param  {Function} callback 組裝成功后將html頁面的$對象返回
 * @return {[type]}            [description]
 */
function makeDom(html, callback) {
  jsdom.env({
    html: html,
    src: [jquery],
    done: function (errors, window) {
      var $ = window.$;
      callback(errors, $);
      window.close();   // 釋放window相關資源,否則將會占用很高的內存
    }
  });
}

借助上面封裝的代碼,現在我們就可以非常方便的使用jQuery在服務端操作html了,尤其是使用jQuery提取信息,示例代碼如下:

makeDom(html, function (errors, $) {
  // 游戲排行列表
  var gameList = $('.ph-bd-list li');
  // 獲取每一個游戲信息
  gameList.each(function () {
    var li = $(this);
    // 游戲信息,各個信息間使用逗號拼接
    var gameInfo = '';
    // 游戲排名
    gameInfo += li.find('span.ttime').text() + ',';
    // 游戲名稱
    gameInfo += li.find('span.game-name a').text() + ',';
    // 熱度值
    gameInfo += li.find('span.type').text() + ',';
    // 測試狀態信息
    gameInfo += $.trim(li.find('span.jhm').text());
    // 輸出抓取的信息
    console.log(gameInfo.white);
    // 將游戲信息保存到文本文件
    fs.appendFileSync('17173_game_rank.csv', gameInfo + '\r\n');
  });
  console.log(('第' + index + '頁抓取完畢').yellow);
  // 設置抓取下一頁
  index++;
  // 執行回調,通知async本次抓取結束
  callback();
});

最終程序跑起來的效果

代碼也來一份吧

代碼加注釋也就100多行,不多,也不復雜,希望能給用到的人帶來點思路。

下載后,先使用npm install命令安裝依賴模塊,然后使用node app.js執行即可。

jsdom在windows上的安裝貌似還有些麻煩,大家參考這篇文章自行解決一下吧:http://www.swordair.com/blog/2012/05/901/

代碼在這


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM