2013-07-24 20 views
7

Próbuję przetestować CasperJS się i są skrobanie terenu, który układ siatki jak:Iteracja na siatce z CasperJS

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

Gdybym nie był przy CasperJS chciałbym pobrać listę wszystkich zawiera (4 w tym przypadku), a następnie uruchom metodę na każdym kontenerze, który może pobrać obiekt o pożądanych właściwościach.

Po prostu wydaje mi się, że ciężko to zrobić w CasperJS. Najpierw próbowałem zwrócić listę elementów DOM w casper.evaluate (function() {....}), ale nie można zwrócić elementów DOM.

Potem próbowałem wykonać każdą pętlę, która wypchnie pożądane obiekty (4) do tablicy i zwróci ją w wartości E, ale będzie zwracać wartość zerową.

Jak można zrobić coś takiego w CasperJS? Czy mogę w jakiś sposób zwrócić kontekst kontenera do metody, która może zwrócić obiekt do głównej oceny, która może zwrócić kolekcję obiektów?

+1

Potrafisz walić głową w główną koncepcję Caspera. Separacja między JS serwera i klienta. Poza oceną, to tylko serwer, bez DOM. Most jest obiektami serializowalnymi. Dwie odpowiedzi wyjaśniają to dobrze. Zwróć uwagę, jak funkcja getLinks w przykładzie zwraca tablicę łańcuchów, a nie węzły DOM.http: //docs.casperjs.org/en/latest/quickstart.html –

Odpowiedz

9

Niestety, nie można dostać złożoną strukturę z evaluate() funkcję, ponieważ przeszedł z evaluate() cokolwiek arg jest rodzajem JSON.parse(JSON.stringify(arg)).

Ale to nie znaczy, że nie jesteś w stanie przekazać innego rodzaju obiektów.

Oto przykład o tym, jak uzyskać tablicę obiektów z 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 

jestem przy założeniu, że kontekst internetowa zawiera bibliotekę jQuery.

Spróbuj uruchomić kod js funkcji evaluate() za pomocą konsoli przeglądarki, aby mieć pewność, że Twój kod js działa zgodnie z oczekiwaniami.

2

Podejście jest poprawne, ale ocena jest piaskownica. Ponadto argumenty i wartość zwracana do funkcji ewaluacyjnej muszą być prostymi obiektami pierwotnymi, ale jeśli mogą być serializowane przez JSON, to jest w porządku. Zamknięcia, funkcje, węzły DOM itp. Nie będą działać!

Zamiast powrocie poszukiwanego przedmiotu, zwraca zserializowaną wersję poszukiwanego obiektu przy użyciu JSON.stringify()

+0

Dziękuję za odpowiedź, ale w jaki sposób byś ją SUSZYŁ. Chciałbym mieć jedną metodę, która może przyjąć kontekst DOM i zwrócić obiekt JSON (uszeregowany). Czy nie będę mógł wywoływać funkcji w obrębie piaskownicy i zwracać element DOM? Zasadniczo po prostu chcę dowiedzieć się, jakie najlepsze rozwiązanie jest do iteracji nad kontenerem i pobrać elementy z tego kontenera w CasperJS. – Dofs

+0

@dofs nie ma DOM poza oceną, po prostu nie możesz tego zrobić. Musisz streścić swoje elementy w proste obiekty serializowalne –