首页  >  问答  >  正文

node.js - node async写的爬虫小程序请求高手指导

var cnodeUrl = "https://segmentfault.com/";

// 存放所有主题链接链接
var topicUrls = [];

/**
 * 所有的url请求完成后,ep控制异步结束,进入每一个主题
 */
ep.after('topic_html', topicUrls.length, function(topics) {

    var concurrencyCount = 0;  // 记录并发数

    /**
     * 进入主题,取得题目
     * @callback topics [{title:''}]
     */
    var fetchUrl = function(myurl, callback) {
        var fetchStart = new Date().getTime();
        concurrencyCount++;
        console.log('现在的并发数是', concurrencyCount, ',正在抓取的是', myurl);

        superagent.get(myurl).end(function(err, ssres) {
            if (err) {
                callback(err, myurl + ' error happened!');
            }
            var time = new Date().getTime() - fetchStart;
            console.log('抓取 ' + myurl + ' 成功', ',耗时' + time + '毫秒');
            concurrencyCount--;

            var $ = cheerio.load(ssres.text);
            var reslut = {
                title: $('.question__author>a>strong').text(),
                answer: $('#answers-title').text()
            };
            callback(null, result);
        })
    }

    // 控制最大并发数为5,在结果中取出callback返回来的整个结果数组。
    async.mapLimit(topicUrls, 5, function (myurl, callback) {
        fetchUrl(myurl, callback);
    }, function (err, result) {
        console.log('===== result: ======\n', result);
        //res.send(result);
    });
})

// 获得所有主题链接 topicUrls
superagent.get(cnodeUrl).end(function(err, sres) {
    if(err) {
        return next(err);
    }
    var $ = cheerio.load(sres.text);
    $('.stream-list').each(function(idx, element) {
        var $element = $(element).find('.title>a');
        var href = url.resolve(cnodeUrl, $element.attr('href'));
        topicUrls.push(href);
    })
    console.log('get authorUrls successful!\n', topicUrls);
    ep.emit('topic_html', 'get topicUrls successful');
})

得到的结果是:

请教一下哪里出了问题?

大家讲道理大家讲道理2764 天前474

全部回复(1)我来回复

  • 阿神

    阿神2017-04-17 14:55:10

    重写了下:

    var async = require('async');
    var cheerio = require('cheerio');
    var superagent = require('superagent');
    
    
    var url = require('url');
    var cnodeUrl = "https://segmentfault.com/";
    
    
    // 存放所有主题链接链接
    var topicUrls = [];
    
    // 获得所有主题链接 topicUrls
    superagent.get(cnodeUrl).end(function(err, sres) {
        if(err) {
            return next(err);
        }
        var $ = cheerio.load(sres.text);
        $('.stream-list__item').each(function(idx, element) {
            var $element = $(element).find('.title>a');
            var href = url.resolve(cnodeUrl, $element.attr('href'));
            topicUrls.push(href);
        })
        // 控制最大并发数为5,在结果中取出callback返回来的整个结果数组。
        async.mapLimit(topicUrls, 5, function (myurl, callback) {
            fetchUrl(myurl, callback);
        }, function (err, result) {
            console.log('===== result: ======', result);
        });
    })
    
    
    function fetchUrl(myurl,callback) {
        var fetchStart = new Date().getTime();
        superagent.get(myurl).end(function(err, ssres) {
            if (err) {
                callback(err, myurl + ' error happened!');
            }
            var time = new Date().getTime() - fetchStart;
            console.log('抓取 ' + myurl + ' 成功', ',耗时' + time + '毫秒');
            // concurrencyCount--;
    
            var $ = cheerio.load(ssres.text);
            var reslut = {
                title: $('.question__author>a>strong').text(),
                answer: $('#answers-title').text()
            };
            callback(null, reslut);
        })
    }

    你上面的代码,我感觉你是参考

    https://github.com/alsotang/node-lessons/blob/master/lesson4/app.js

    这个课程写的吧,应该是你用的eventproxy方式不正确

    回复
    0
  • 取消回复