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し、リンクを保持する場合はtrueの値を返し、そうでない場合は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;
});
于 2012-09-15T19:26:05.383 に答える
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 に答える
0

が false の場合、マッピング関数は何も返さないため、links配列内の一部の項目はです。undefinedmatchesWhitelist

その他の問題: ページ上のすべてのリンクにスパンを含める必要はありません。then にアクセスするinnerHTMLと、関数が壊れます。And: 既にクロールされた一連のページが表示されません。循環リンクは、クローラーを無限ループに導きます。

于 2012-09-15T18:39:09.240 に答える