2013-02-10 54 views
2

這裏返回null元素是我運行該腳本: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 : '[email protected]', 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(); 

一切順利,直到地圖調用的內部循環,特別是console.log(elem.innerHTML)schools_arr中的許多元素爲空。如果我在console.log聲明周圍添加if(elem != null) { ... },那麼一切都很好,但是這樣做會使這一點失敗。當我在頁面的Chrome控制檯中運行相同的document.querySelectorAll時,NodeList中的513個元素都不爲空。 CasperJS也報告了513個元素,但它顯示了很多爲空。這裏發生了什麼?頁面是否完全加載?如果這是一個新手的錯誤,我從未使用過CasperJS。

回答

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; 
    }); 
} 
+0

這似乎有很大的意義,但確切的getSchools方法(最上面的一個)似乎在映射之後返回null ......任何想法爲什麼它可能會使整個數組爲空?刪除地圖調用讓我回到我所在的地方,非空元素爲空元素... – 2013-02-10 18:27:48

+0

因爲在頁面env和casper/phantom之間沒有簡單的橋接;記住,你可以從evaluate()調用中檢索到的所有東西總是可以通過'JSON.stringify'(HTMLElements,NodeList不是)序列化的。 – NiKo 2013-02-10 20:49:52

+1

那麼如果你的答案不起作用,那麼首選方法是什麼?我想要的是頁面上所有div的文本內容與「鏈接」類。這真的不應該太難。 – 2013-02-10 21:42:43