• 使用nodejs抓取博客园内容---Promise模块探索


    最近在学习NodeJs。从nodejs语言本身,看了朴灵的《深入浅出NodeJs》,《Node即学即用》。个人感觉朴灵的这本书适合node入门后乃至中级程序员去阅读。而后者则可以完全当做初级入门教材使用。当然我认为最快捷的学习路径是看视频。这里推荐  慕课网的node视频,讲的还是非常不错的。虽然说nodej是Javascript在服务端的一种表现,严格来说算不上说是一种新的语言。连官方也说,其强大的性能来源于google的v8引擎。换句话说,以前Javascript在客户端的浏览器里运行。PC机器为浏览器预留了一大块内存空间,在浏览器建立了一个JavaScript解释器,也就是V8引擎。只是Ryna Dahl把这个引擎移动到了服务端。

    了解完这个这个前提之后,就能揭开NodeJs的神秘面纱了。至于NodeJs于JavaScript在表现上有何异同,大家可以去参考相对基础的文章去了解基础知识。如果JavaScript还不太了解,还是建议阅读《JavaScript权威指南》(犀牛书虽然特别大部头,但是读起来特别爽快,就好像Javascipt大牛跟你面对面交流似得,好像他就知道你这里不懂,真是贴心到想哭)。学完了nodejs和一些核心包,以及数据库框架,终于准备动手做一些东西了。在做的过程中也对nodejs有了更深的了解,其中最大的坑也就是nodejs的异步执行,这也是nodejs的最大特点。后来了解到Promise这个Es6的新特性。可以让代码的流程执行的更加清晰明了。

    推荐http://www.cnblogs.com/lvdabao/p/es6-promise-1.html

    下面是使用nodejs抓取博客园前10页所有的文章标题和文章对应的链接。代码中有详细注释,有问题的可以评论区讨论。

      1 var http = require('http');   //引入nodejs的http模块,该模块用于构建http服务和作为HttpClient使用。
      2 var promise = require('promise'); //对异步编程进行流程控制,更加符合后端程序员的编程习惯。
      3 var cheerio = require('cheerio'); //可以理解为服务端的Jquery。使用方法和客户端一样。
      4 
      5 var url = 'http://www.cnblogs.com/#p'; //要抓取的网址。博客园的页数是通过添加锚点的,后面有拼接
      6 
      7 
      8 //Promise 在任何情况下都处于以下三种状态中的一种:
      9 //未完成(unfulfilled)、已完成(resolved)和拒绝(rejected)
     10 //事件已完成则使用成功的callback(resolve)返回自身,失败了则
     11 //选择使用callback(reject)来返回失败的自身。
     12 
     13 function getPageList(url){
     14     //return Promise对象
     15     return new Promise(function(resolve,reject) {
     16         http.get(url,function(res) {
     17             var body = '';
     18 
     19             //当接受到数据的时候,http是执行范围请求的。所以每个范围请求就是一个chunk。
     20             res.on('data', function(chunk) {
     21                 //buffer是一种node处理二进制信息的格式,不必理会。
     22                 res.setEncoding('utf8'); //设置buffer字符集
     23                 body += chunk;           //拼接buffer
     24             });
     25 
     26             //当整个http请求结束的时候
     27             res.on('end', function() {
     28                 var $ = cheerio.load(body);  //将html变为jquery对象。
     29                 var articleList = $('.post_item');
     30                 var  articleArr = [];
     31                 articleList.each(function() {
     32                     var curEle = $(this);
     33                     var title  = curEle.find('.post_item_body h3').text();  //获取标题
     34                     var href = curEle.find('.post_item_body h3 a').attr('href'); //文章链接
     35                     articleArr.push({
     36                         title:title,
     37                         href:href
     38                     });
     39                    
     40 
     41                 });
     42                 
     43                 //成功的状态使用resolve回调函数。
     44                 resolve(articleArr);
     45 
     46             });
     47 
     48             //当执行http请求失败的时候,返回错误信息
     49             res.on('error', function(e) {
     50                 reject(e.message);
     51             });
     52 
     53 
     54 
     55         })
     56     })
     57 }
     58 
     59 
     60 //请求博客园前10页的数据。将所有的请求预先放置在集合内。
     61 var list = [];
     62 for(var i=1;i<=10;i++) {
     63     var url = url+i;
     64     list.push(getPageList(url));
     65 
     66 }
     67 
     68 //调用Promise的下面的all方法。参数是一个事件集合。
     69 //Promise将会进行异步执行。但是最后的返回时机要根据最耗时的那个请求为标准。
     70 //then(),可以接受两个参数(callback).第一个参数是成功(resolved)的回调。
     71 //第二个参数是执行上个操作失败(rejected)的回调。
     72 Promise
     73     .all(list)
     74     .then(function(data) {
     75         console.dir(data);
     76     })
    

     以下是结果:

    此前工作繁忙,这段时间空下来了。从今天起,将会陆续介绍nodejs或者是其他方面的东西。

  • 相关阅读:
    ubuntu实时显示网速cpu占用和内存占用率
    删除以....开头的所有文件
    0.0.....1 至 0.99.......9 之间正则
    引入腾讯视频播放,可控制是否暂停播放
    解决微信小程序textarea层级太高遮挡其他组件的问题
    查看某分支推送记录
    小程序下载canvas生成图片
    微信小程序企业付款到个人
    秒 转化为 时:分:秒 ------- 类似倒计时
    iOS--崩溃日志的格式化分析---格式化crash日志
  • 原文地址:https://www.cnblogs.com/roverliang/p/5340902.html
Copyright © 2020-2023  润新知