javascript - 超出最大调用堆栈大小 Node.JS WebCrawler

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

我用 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");
});

如果有任何帮助,我将不胜感激。

非常感谢,

最大

最佳答案

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

关于javascript - 超出最大调用堆栈大小 Node.JS WebCrawler,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30142101/

相关文章:

javascript - 如何从 Javascript 中的 POST 请求读取 JSON 值

javascript - 带 Node 的 OpenVPN,它是如何工作的?

mysql - MySQL INSERT for POST 方法的正文不正确

process - powershell v2 - 如何获取进程 ID

c# - 注册流程开始时间的最佳方式?

javascript - 在 React 中,如何在条件语句中拥有动态变量名?

javascript - 具有匿名函数的三元运算符

javascript - 根据浏览器窗口大小调整 JS 模式对话框

javascript - 如何在 Angular 6 中循环链接 Promise

c# - C# 如何知道某个文件将触发哪个进程