【问题标题】:Maximum Call Stack Size exceeded Node.JS WebCrawler超出最大调用堆栈大小 Node.JS WebCrawler
【发布时间】:2015-05-09 16:00:42
【问题描述】:

我在 Node.JS 中编写了这个 WebCrawler。它抓取页面并将其保存到 Redis 中。我使用了 setImmediate 和 process.nextTick,但它仍然会抛出这个错误。我做错了什么?

var $, client, f, redis, request, s, urlhelper, urls, validator, _;

request = require("request");

validator = require("validator");

$ = require("cheerio");

_ = require("underscore");

s = require("underscore.string");

urlhelper = require("url");

urls = [];

redis = require("redis");

client = redis.createClient();

f = function(url) {
    return process.nextTick(function() {
        urls.push(url);
        if (validator.isURL(url) !== true) {
            return;
        }
        return request(url, function(error, response, body) {
            var title, _$;
            if (!error && response.statusCode === 200) {
                _$ = $.load(body);
                title = _$("title").text() || "";
                return client.hset(url, "title", title, function() {
                    return _.each(_$("a"), function(object) {
                        var href;
                        href = object.attribs["href"];
                        if (!validator.isURL(href)) {
                            href = urlhelper.resolve(url, href || "");
                        }
                        console.log(href);
                        return client.exists(href, function(error, reply) {
                            if (error) {
                                throw error;
                            }
                            if (reply === 1) {
                                return client.hincrby(href, "refs", 1, function() {});
                            } else {
                                return client.hmset(href, {
                                    "refs": "1",
                                    "title": ""
                                }, function() {
                                    return client.sadd("sites", href, function() {
                                        return setTimeout(function() {
                                            return f(href);
                                        }, 0);
                                    });
                                });
                            }
                        });
                    });
                });
            }
        });
    });
};

client.on("connect", function() {
    return f("http://www.apple.com");
});

我将不胜感激。

非常感谢,

最大

【问题讨论】:

    标签: javascript node.js process web-crawler search-engine


    【解决方案1】:

    你有一个递归函数,它必须在完成之前爬过整个万维网(或者至少,从 www.apple.com 开始可以访问的所有内容)。除非它可以在内存中保存数十亿个网页,否则它将耗尽堆栈空间。您需要重写它,以便在某种数据库中维护一个单独的页面队列以进行爬网——这不是您可以使用递归的地方。或者,您可以设置递归的最大深度。

    【讨论】:

      猜你喜欢
      • 2014-01-23
      • 2015-02-07
      • 1970-01-01
      • 2012-05-27
      • 2016-12-04
      • 2014-12-03
      • 1970-01-01
      • 2015-10-24
      • 2015-12-29
      相关资源
      最近更新 更多