alsotang / node-lessons

:closed_book:《Node.js 包教不包会》 by alsotang
16.54k stars 4.7k forks source link

lesson4 挑战部分代码及个人理解 初学小白一只 #95

Open yjg159 opened 8 years ago

yjg159 commented 8 years ago

var eventproxy = require('eventproxy'); var superagent = require('superagent'); var cheerio = require('cheerio'); // url 模块是 Node.js 标准库里面的 // http://nodejs.org/api/url.html var url = require('url');

var cnodeUrl = 'https://cnodejs.org/';

superagent.get(cnodeUrl) .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); // $element.attr('href') 本来的样子是 /topic/542acd7d5d28233425538b04 // 我们用 url.resolve 来自动推断出完整 url,变成 // https://cnodejs.org/topic/542acd7d5d28233425538b04 的形式 // 具体请看 http://nodejs.org/api/url.html#url_url_resolve_from_to 的示例 if(idx<5){ var href = url.resolve(cnodeUrl, $element.attr('href')); topicUrls.push(href); } }); // 得到 topicUrls 之后

// 得到一个 eventproxy 的实例
var ep = new eventproxy();

// 命令 ep 重复监听 topicUrls.length 次(在这里也就是 40 次) `topic_html` 事件再行动
ep.after('topic_html', topicUrls.length, function (topics) {
  // topics 是个数组,包含了 40 次 ep.emit('topic_html', pair) 中的那 40 个 pair

  // 开始行动
  topics = topics.map(function (topicPair) {//这里的topicPair 是将topics 转换成map的意思 ,而topic在上面有解释
    // 接下来都是 jquery 的用法了
    var topicUrl = topicPair[0];
    var topicHtml = topicPair[1];
    var score = topicPair[2];
    var $ = cheerio.load(topicHtml);

    //注意!!获取积分不能从这里获取,因为这里只是从topics里面读数据,没办法向里面塞数据,所以应该在ep.emit()的时候就读积分
    //这里来获取第一个评论用户的个人信息的url
    //var author1href =  $('.author_content').find('a').attr('href');
    //var author1_href = url.resolve(cnodeUrl,author1href);
    //
    //var s = 0;
    ////现在我们需要从上面获得的url进入第一个评论的用户的个人主页去获得其社区积分
    //superagent.get(author1_href)
    //    .end(function(err,res){
    //      if(err)
    //        return console.error(err);
    //      var $$ = cheerio.load(res.text);
    //
    //      var score = $$('.user_profile .unstyled .big').eq(0).text().trim();
    //
    //      console.log(score);
    //    }
    //
    //);

    return ({
      title: $('.topic_full_title').text().trim(),
      href: topicUrl,
      comment1: $('.reply_content').eq(0).text().trim(),
      author1: $('.user_info .dark').eq(0).text().trim(),
      //author1_href:author1_href,
      score: score
    });

  });

  console.log('final:');
  console.log(topics);
});

topicUrls.forEach(function (topicUrl) {
  superagent.get(topicUrl)
    .end(function (err, res) {
      console.log('fetch ' + topicUrl + ' successful');

        var $ = cheerio.load(res.text);
        var author1href =  $('.author_content').find('a').attr('href');
        var author1_href = url.resolve(cnodeUrl,author1href);
        var score = 0;
        //现在我们需要从上面获得的url进入第一个评论的用户的个人主页去获得其社区积分
        superagent.get(author1_href)
            .end(function(err,response){
              if(err)
                return console.error(err);
              var $ = cheerio.load(response.text);
              var ss = $('.user_profile .unstyled .big').eq(0).text().trim();
              score = ss;
              // console.log(score);
              ep.emit('topic_html', [topicUrl, res.text,score]);//这个中括号里面的就是上面的 topic 作为参数传进去的
            }
        );
        //读出来的score在读出来的时候就要ep.emit(),到外面貌似无效了.
      //ep.emit('topic_html', [topicUrl, res.text,score]);//这个中括号里面的就是上面的 topic 作为参数传进去的
    });
});

});

yjg159 commented 8 years ago

因为读全部数据所以我只读了前5条.代码中的不足之处在于如果读全部帖子有的帖子没有回复,所以第一条回复不存在,会报错,所以要在那里加判断是否有评论

ExcellentJR commented 7 years ago

先给个默认值就行了,我看了下有的帖子评论是有的,但是没取到