0

我正在尝试使用用于解析页面和提取相关链接的 CasperJS 编写蜘蛛。有问题的站点具有文件和文件夹的分层视图。我已经编写了一个递归方法来执行文件结构的导航,但是在该方法的第一次迭代之后,我的数组返回 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
            };
        });
    }

谢谢

4

3 回答 3

2

你似乎想要一个减少的集合。

这意味着您应该使用.filter而不是.map,如果要保留链接,则返回真值,否则返回假值。

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;
});
于 2012-09-15T19:26:05.383 回答
0

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

其他问题:并非页面上的所有链接都需要包含跨度。访问innerHTMLthen 会破坏你的功能。并且:我看不到一系列已经抓取的页面。任何循环链接都会导致您的爬虫陷入无限循环。

于 2012-09-15T18:39:09.240 回答
0

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

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

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

于 2012-09-16T11:05:55.203 回答