CasperJS在NodeList中返回null元素

Sam*_*ern 2 javascript document nodelist casperjs

这是我正在运行的脚本:

//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();
Run Code Online (Sandbox Code Playgroud)

一切都很好,直到地图调用的内部循环,特别是console.log(elem.innerHTML).许多元素schools_arr都是null.如果我加一个if(elem != null) { ... }console.log声明这一切都很好,但是这违背了点.当我document.querySelectorAll在页面上的Chrome控制台中运行相同内容时,NodeList中的513个元素都不为空.CasperJS还报告了513个元素,但它显示许多元素为null.这里发生了什么?页面是否未完全加载?我之前从未使用过CasperJS,如果这是一个新手的错误,那就很抱歉.

NiK*_*iKo 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;
    });
}
Run Code Online (Sandbox Code Playgroud)

虽然我不知道你可以用节点innerHTML字符串内容做什么...所以通常最好将元素映射到你需要的确切属性:

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

编辑:根据评论中的要求,获取所有链接的内部文本:

function getSchools() {
    var arr = document.querySelectorAll('div.link a');
    return Array.prototype.map.call(arr, function(elem) {
        return elem.textContent;
    });
}
Run Code Online (Sandbox Code Playgroud)