How can I wait for a socket.io connection to return data using casperJS?

纵饮孤独 提交于 2019-12-01 12:39:16

问题


I am scraping a page which uses socket.io to populate some select tag options. How can I wait for the socket to receive data before evaluating the page? I am using casperJS

the socket code (loaded by the target site):

socket.on('list', function (data) {


$.each(data.match_names, function (id, name) {
    if (some condition) {
        /*nothing*/
    } else {
        if (typeof( varname ) == 'function') {
            $('#myselector').append('<option value="' + id + '">' + name + " " + get_tournament_name(id.substr(0, 4)) + '</option>');
        } else {
            $('#myselector').append('<option value="' + id + '">' + name + '</option>');
        }
        match_count++;
    }
});

I check that the socket.io script has loaded:

casper.waitForResource("socket.io.js", function() {
    this.echo('socket.io has been loaded.'); //is printed

//how can I check that data has arrived from 'socket.on('list', function (data)' ?
});

But the option tags are not on the page, presumably because I am evaluating the page too soon

casper.then(function() {
    baseTargetUrl = this.evaluate(function() {
        return __utils__.getElementByXPath('//*[@id="wrapper"]/div[1]/a[2]')["href"];
    });
    console.log('logging: '+baseTargetUrl); // works

    casper.thenOpenAndEvaluate(baseTargetUrl ,function() { //baseTargetUrl is no longer undefined, it's a closure now

        $(function(){ // DOM is ready

            var myOptions = [] ;

            $('select#myselector option').each(function(){
                myOptions.push( $(this).text() + ' : '+$(this).val() ); //additional options have not yet been added

            });

        });
    });
});

回答1:


You could do something like the following as lud1977 describes I guess, although I don't like it. Casper's waitFor works by polling, while that's really stupid when waiting for an event to happen. It would be way better if you do this:

var list = null; // broader scope

casper.on('socket.list', function() {
  // do stuff with <list> here
});

casper.waitForResource("socket.io.js", function() { 
  var socket = io.connect("http://wherever-the-server-is")
  socket.on('list', function(data){
    list = data;
    this.emit('socket.list');
  }.bind(this));
})

Source: http://docs.casperjs.org/en/latest/events-filters.html




回答2:


i suggest you take a look at this page: how to wait for element visibility in phantomjs

particularly the waitfor function. In the situation you described, I would use something like that to check if the page has been populated with data from the socket, meaning the socket has finished loading.

Hope it helps.



来源:https://stackoverflow.com/questions/20937627/how-can-i-wait-for-a-socket-io-connection-to-return-data-using-casperjs

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