关于 node 爬虫问题
发布于 1天前 作者 iamocean 129 次浏览 来自 问答

最近在看<包教不包会>教程,遇到上一些问题不太明白

  1. 为什么会有时能爬到数据,有时却爬不到数据呢?
  2. async.mapLimit 这个接口有点疑问?这个是每爬完一条 url 就返回的结果数据吗?如果是,那么我怎样才能知道所有数据已爬完毕呢?

代码如下:

var express = require('express');
var superagent = require('superagent');
var cheerio = require('cheerio');
var url = require('url');
var async = require('async');

var app = express();

app.get('/', function(req, res){
  var targetUrl = 'https://cnodejs.org';
  superagent.get(targetUrl).end(function(err, html){
    if(err){
      console.error('urls: ', err);
    }

    var $ = cheerio.load(html.text);
    var urls = [];
    // 获取所有链接
    $('#topic_list .topic_title').each(function(key, value){
      var $obj = $(value);
      var href = $obj.attr('href');
      var link = url.resolve(targetUrl, href)

      urls.push(link);
    });

    // 定义当前并发数
    var concurrencyCount = 0;
    function fetchUrls(url, callback){
      // 抓取单条主题的内容
      var topic = {};
      superagent.get(url).end(function(err, thtml){
        var $ = cheerio.load(thtml);
        var title = $('#content .topic_header .topic_full_title').text().trim();
        var content = $('#content .topic_content .markdown-text').text().trim();
        var link = url;

        topic = {
          "title" : title,
          "content" : content,
          "link" : link
        };
      });

      // 随机间隔时间
      var delay = parseInt((Math.random() * 10000000) % 3000, 10);
      concurrencyCount++;
      console.log('当前并发数是'+ concurrencyCount +', 正在抓取的是'+ url +', 耗时'+ delay + '毫秒.');

      setTimeout(function(){
        concurrencyCount--;
        callback(null, topic);
      }, delay);
    }

    // 控制并发数
    async.mapLimit(urls, 3, function(url, callback){
      fetchUrls(url, callback);
    }, function(err, result){
      if(err){
        console.error('final: ', err);
      }

      console.log('final: ', result);
      res.send(result);
    });
  });

});

app.listen(4000, function(){
  console.log('hello cnodejs.');
});

谢谢你看到这里.

1 回复

如果数据是js动态生成的,不等页面load完是读取不到的,可以看下http://phantomjs.org

回到顶部