2013-07-24 32 views
7

Tôi cố gắng để kiểm tra CasperJS ra, và được cạo một trang web trong đó có một bố trí lưới điện như:iterating trên một mạng lưới với CasperJS

|Name  |Name  | 
|Title  |Title  | 
|Image  |Image  | 
|Something |Something | 
|---------------------- 
|Name  |Name  | 
|Title  |Title  | 
|Image  |Image  | 
|Something |Something | 
|---------------------- 

Nếu tôi đã không sử dụng CasperJS tôi sẽ lấy danh sách tất cả chứa (4 i trường hợp này) và sau đó chạy một phương pháp trên mỗi container có thể lấy một đối tượng với các thuộc tính mong muốn.

Tôi dường như có một thời gian khó làm việc này trong CasperJS. Trước tiên, tôi đã cố gắng trả về danh sách các phần tử DOM trong casper.evaluate (function() {....}), nhưng nó không thể trả về các phần tử DOM.

Sau đó, tôi đã cố gắng thực hiện một vòng lặp mà sẽ đẩy các đối tượng mong muốn (4) vào một mảng và trả về nó trong một Đánh giá, nhưng nó tiếp tục trả về giá trị rỗng.

Làm cách nào để thực hiện một việc như thế này trong CasperJS. Tôi có thể bằng cách nào đó trả về một bối cảnh của một container để một phương pháp, mà có thể trả lại đối tượng để đánh giá chính, mà có thể trả lại bộ sưu tập của các đối tượng?

+1

Bạn đang đập đầu vào khái niệm chính của Casper. Sự tách biệt giữa máy chủ và máy khách JS. Ngoài đánh giá, chỉ có máy chủ, không có DOM. Cây cầu là các đối tượng có thể tuần tự. Hai câu trả lời giải thích tốt. Lưu ý cách hàm getLinks trong ví dụ trả về một mảng các chuỗi, chứ không phải các nút DOM.http: //docs.casperjs.org/en/latest/quickstart.html –

Trả lời

9

Thật không may, bạn không thể có được một cấu trúc phức tạp từ evaluate() chức năng, bởi vì bất cứ điều gì arg truyền từ evaluate() là loại JSON.parse(JSON.stringify(arg)).

Nhưng điều đó không có nghĩa là bạn không thể vượt qua một loại đối tượng khác.

Dưới đây là một ví dụ về cách nhận được một mảng với các đối tượng từ casper.evaluate():

var arrayResult = this.evaluate(function getGridResuls(){ 

    //create array 
    var arrayObjects = new Array(); 

    //Iterates over table (grid) elements 
    jQuery("table.results").each(function(index) { 

     //get table (grid) 
     var tableResult = jQuery(this); 

     //create basic object  
     objResult = new Object(); 

     //fill object properties 
     objResult.name  = tableResult.find('selector to get name').text(); 
     objResult.title  = tableResult.find('selector to get title').text(); 
     objResult.image  = tableResult.find('selector to get image info').text(); 
     objResult.something = tableResult.find('selectot to get something').text().trim(); 

     //assign object to array 
     arrayObjects[index] = objResult; 

    }); 

    //return array with objects 
    return arrayObjects; 

}); 

... 
//do something with arrayResult 

Tôi giả định rằng bối cảnh web bao gồm các thư viện JQuery.

Mẹo: cố gắng chạy mã js của chức năng evaluate() bằng cách sử dụng bảng điều khiển trình duyệt để đảm bảo mã js của bạn hoạt động như mong đợi.

2

Cách tiếp cận là chính xác nhưng đánh giá là hộp cát. Ngoài ra, các đối số và giá trị trả về cho hàm đánh giá phải là một đối tượng nguyên thủy đơn giản nhưng nếu nó có thể được tuần tự hóa thông qua JSON, thì nó là tốt. Đóng cửa, chức năng, nút DOM, v.v. sẽ không hoạt động!

Thay vì trả lại đối tượng truy nã, trả về một phiên bản serialized đối tượng truy nã sử dụng JSON.stringify()

+0

Cảm ơn câu trả lời của bạn, nhưng làm thế nào bạn sẽ DRY nó lên. Tôi sẽ có một phương pháp mà có thể mất một ngữ cảnh DOM và trả về một đối tượng JSON (được xâu chuỗi). Tôi sẽ không thể gọi các hàm trong hộp cát và trong đó trả về phần tử DOM? Về cơ bản, tôi chỉ muốn tìm ra giải pháp tốt nhất là lặp qua một thùng chứa, và lấy các phần tử ra khỏi thùng chứa đó trong CasperJS. – Dofs

+0

@ không có DOM bên ngoài đánh giá, bạn chỉ không thể làm điều đó. Bạn phải trừu tượng các phần tử của mình thành các đối tượng serializable đơn giản –