数组在递归方法中设置为null

Array being set to null in recursive method

本文关键字:null 设置 递归方法 数组      更新时间:2023-09-26

我正试图使用CasperJS编写一个spider,用于解析页面和提取相关链接。有问题的网站具有文件和文件夹的分层视图。我已经编写了一个递归方法来执行对文件结构的导航,但在该方法的第一次迭代后,即使函数运行正确,我的数组仍返回null。如有任何帮助,我们将不胜感激。

var processPage = function() {
    //Gather links
    var links = this.evaluate(function() { //links is the array being set to null
        var elements = document.querySelectorAll("a");
        return Array.prototype.map.call(elements, function(e) {
            //check link matches our white list
            var matchesWhitelist = false;
            var fileDescription = e.querySelector("span").innerHTML;
            console.log("span text:" + fileDescription);
            //begin checking
            if (fileDescription.indexOf('.mp3') != -1) matchesWhitelist = true;
            //if (fileDescription.indexOf('.wmv') != -1) .... etc
            //failing that is the link for a folder rather than a file
            var hrefLink = e.getAttribute("href");
            if (hrefLink.indexOf('folder-files') != -1) matchesWhitelist = true;
            if (matchesWhitelist) {
                console.log('match');
                console.log('Adding link: ' + hrefLink)
                return hrefLink;
            }
            else {
                console.log('no match');
            }
        });
    });
console.log("linkslength: " + links.length); // links will be null upon recursion
for (var i = 0; i < links.length; i++) {
        //check link matches our 'whitelist'
        this.thenOpen("https://TLD" + links[i]).then(function() {
            this.echo("New URL: " + this.getCurrentUrl());
            //check for files
            if (this.exists(".fileDownload")) {
                //extract link
            } else {
                //assume that this is a 'folder' link and send to be processed for more links
                casper.then(processPage); //continue recursion
            };
        });
    }

感谢

您似乎想要一个约简集。

这意味着您应该使用.filter而不是.map,如果希望保留链接,则返回truthy值,如果不希望,则返回false值。

return Array.prototype.filter.call(elements, function(e) {
     //...
    if (matchesWhitelist) {
        console.log('match');
        console.log('Adding link: ' + hrefLink)
        return true;
    }
    else {
        console.log('no match');
    }
});

如果您不需要日志记录,您只需要返回matchesWhitelist

return Array.prototype.filter.call(elements, function(e) {
     //...
    return matchesWhitelist;
});

所以,去掉日志记录,您可以将过滤器减少到这个级别。

return Array.prototype.filter.call(elements, function(e) {
    return e.getAttribute("href").indexOf('folder-files') != -1 ||
           e.querySelector("span").innerHTML.indexOf('.mp3') != -1;
});

links数组中的某些项是undefined,因为如果matchesWhitelist为false,则映射函数不会返回任何内容。

其他问题:并非页面上的所有链接都需要包含跨度。访问innerHTML会破坏您的功能。而且:我看不到已经爬网的页面数组。任何循环链接都会让你的爬虫陷入无尽的循环。

我希望我能接受你的两个答案,因为它们都有助于我找到问题的根源。我一直在把事情搞得过于复杂,通过首先应用过滤器将集合减少到我需要的元素,然后执行映射,这样我就可以返回一个只包含所需链接的数组,从而解决了这个问题。我最终使用的代码是

var processPage = function() {
    var url;
    //Gather links
    var links = this.evaluate(function() {
        var elements = document.querySelectorAll("a");
        var filteredElementsList = Array.prototype.filter.call(elements, function(e) {
            //check link matches our white list
            var matchesWhitelist = false;
            var fileDescription = e.querySelector("span").innerHTML;
            console.log("span text:" + fileDescription);
            //begin checking
            if (fileDescription.indexOf('.mp3') != -1) matchesWhitelist = true;
            //failing that is the link for a folder rather than a file
            var hrefLink = e.getAttribute("href");
            if (hrefLink.indexOf('folder-files') != -1) matchesWhitelist = true;
            if (matchesWhitelist) {
                console.log('match');
                console.log('Adding link: ' + hrefLink)
            } else {
                console.log('no match');
            }
            return matchesWhitelist;
        });
        return Array.prototype.map.call(filteredElementsList, function(e) {
            return e.getAttribute("href");
        });
    });

脚本现在工作,并提取了我需要的每一个链接。再次感谢您的帮助。