2

これが私が実行しているスクリプトです:

//Require CasperJS
var casper = require('casper').create();

//Scraping Courserank
var base = "https://www.courserank.com";
var home = base + "/w/home";
var schools = base + "/w/schools?switchSchool=1";

//First, navigate to homepage and login
casper.start(home, function() {
    console.log('Logging in...');
    //Fill in the login form
    this.fill(
            'form[action="login"]', 
            { username : 'hatboysam@gmail.com', password : "****" },
            true
            );
});

function getSchools() {
    var arr = document.querySelectorAll('div.link');
    return arr;
}

//Go to the schools page
casper.then(function() {
    console.log(this.getCurrentUrl());
    //Open the school choice page
    casper.open(schools).then(function() {
        console.log(this.getCurrentUrl());
        //Get all school links
        var schools_arr = this.evaluate(getSchools);
        console.log(schools_arr.length);
        Array.prototype.map.call(schools_arr, function(elem) {
            console.log(elem.innerHTML);
        });
    });
});

casper.run();

map 呼び出しの内側のループまで、特にconsole.log(elem.innerHTML). の要素の多くschools_arrは null です。if(elem != null) { ... }ステートメントの前後に追加しconsole.logても問題ありませんが、それはポイントを無効にします。document.querySelectorAllページの Chrome コンソールで同じことを実行すると、NodeList の 513 要素はどれも null ではありません。CasperJS も 513 個の要素を報告しますが、多くは null として表示されます。何が起きてる?ページが完全にロードされていませんか? これまで CasperJS を使用したことがないため、これが初心者の間違いである場合は申し訳ありません。

4

1 に答える 1

5

evaluate();を使用してページコンテキストからネイティブノード要素を返すことはできません。Array#mapで逆シリアル化できるものにする必要がありますJSON.parse

したがって、getSchools()関数は次のようなことを行う必要があります。

function getSchools() {
    var arr = document.querySelectorAll('div.link');
    return Array.prototype.map.call(arr, function(elem) {
        return elem.innerHTML;
    });
}

ノードinnerHTML文字列コンテンツで何ができるかわかりませんが…したがって、通常は、要素を必要な正確なプロパティにマップすることをお勧めします。

function getSchools() {
    var arr = document.querySelectorAll('div.link a');
    return Array.prototype.map.call(arr, function(elem) {
        return elem.getAttribute('href');
    });
}

編集:コメントで要求されているように、すべてのリンクの内部テキストをフェッチするには:

function getSchools() {
    var arr = document.querySelectorAll('div.link a');
    return Array.prototype.map.call(arr, function(elem) {
        return elem.textContent;
    });
}
于 2013-02-10T08:27:23.413 に答える