Iterating over a grid with CasperJS

非 Y 不嫁゛ 提交于 2019-12-08 19:41:49

问题


I am trying to test CasperJS out, and are scraping a site which has a grid layout like:

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

If I wasn't using CasperJS I would retrieve a list of all the contains (4 i this case) and then run a method on each container which could retrieve an object with the wanted properties.

I just seem to have a hard time of doing this in CasperJS. First I tried to return the list of DOM elements in casper.evaluate(function(){....}), but it can't return DOM elements.

Then I tried to make an each loop which would push the wanted objects (4) to an array and return it in an Evalue, but it keeps returning null.

How would one go about doing something like this in CasperJS. Can I somehow return a context of a container to a method, which can return the object to the main evaluate, which can the return the collection of the objects?


回答1:


Unfortunately, you can't get a complex structure from evaluate() function, because whatever arg passed from evaluate() is sort of JSON.parse(JSON.stringify(arg)).

But it doesn't mean that you are not able to pass another kind of objects.

Here an example about how get an array with objects from 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

I'm assuming that the web context includes the JQuery library.

Tip: try to run the js code of the evaluate() function by using the browser console in order to be sure that your js code is working as expected.




回答2:


The approach is correct but evaluate is sandboxed. In addition, the arguments and the return value to the evaluate function must be a simple primitive object but if it can be serialized via JSON, then it is fine. Closures, functions, DOM nodes, etc. will not work!

Instead of returning wanted object, returns a serialized version of wanted object using JSON.stringify()



来源:https://stackoverflow.com/questions/17842979/iterating-over-a-grid-with-casperjs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!