zoukankan      html  css  js  c++  java
  • 借助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
    ');
    req.write('data
    ');
    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 + '
    ');
      });
      console.log(('第' + index + '页抓取完毕').yellow);
      // 设置抓取下一页
      index++;
      // 执行回调,通知async本次抓取结束
      callback();
    });

    最终程序跑起来的效果

    代码也来一份吧

    代码加注释也就100多行,不多,也不复杂,希望能给用到的人带来点思路。

    下载后,先使用npm install命令安装依赖模块,然后使用node app.js执行即可。

    jsdom在windows上的安装貌似还有些麻烦,大家参考这篇文章自行解决一下吧:http://www.swordair.com/blog/2012/05/901/

    代码在这

  • 相关阅读:
    Struts2框架的学习遇到的问题1
    博客开通第100天
    RTK(Real Time Kinematic)实时动态差分定位技术
    HSRP 协议/ VRRP 协议(热备份路由协议)
    PKI 公钥基础设施
    路由器的工作原理
    VLAN基础知识
    Linux系统的 粘滞位、sgid和suid
    Kali Linux三步安装中文输入法(极简)
    ACL 包过滤技术
  • 原文地址:https://www.cnblogs.com/jasondan/p/3495742.html
Copyright © 2011-2022 走看看