Call function PhantomJs

2019-04-16 07:22发布

问题:

I'm new in Java Script and i need help :) I want to call function ( set_calendar_date() ) and then get page innerHTML.

<a onclick="set_calendar_date('1'); return false;" href="#">

<span>

    26/02 We

</span>

PhantomJs code :

page.open(url, function (status) {
if (status !== 'success') 
{
            console.log('Unable to access network');
    } 
else 
{
    var events = page.evaluate(function () {
            // here i want to call set_calendar_date();
            return document.getElementById('fs').innerHTML;
        });
    var file= require('fs');
    file.write('results.txt',events,'w+');

phantom.exit();
}});

回答1:

It seems that the function set_calendar_date when executed will load content through ajax or do some processing to generate content. This content will be placed somewhere, possibly inside an element with id fs.

Considering the asynchronous nature of this process, you can not directly return the innerHTML just after calling the function (you may either get the old data or nothing at all).

What I would suggest is to call the function inside evaluate

    page.evaluate(function () {
        set_calendar_date('1');
    });

Next, you need to understand the nature of the "update". Find an element that can help in programmatically determine that the update is complete or not-yet-complete. Say, for instance, if the innherHTML of the element with id fs is empty the content is not yet updated.

And then keep checking for change in the target element (vis, fs). You can keep checking this using window.setInterval.

The code can be similar to:

page.evaluate(function () {
   set_calendar_date('1');
});

var waiter = window.setInterval(function(){
  var fsContent = page.evaluate(function(){
     var elm = document.getElementById('fs');
     return elm && elm.innerHTML || false;
  });
  // if content is found
  if (fsContent !== false) {
     window.clearInterval(waiter);
     var file= require('fs');
     file.write('results.txt',fsContent,'w+');
  }

}, 300);

NOTE: This can be implemented with simpler code using CasperJS, a wrapper around PhantomJS. CasperJS provides a number of functions to do this easily like using waitForSelectorTextChange() or waitFor(), waitForSelector() or waitWhileSelector() etc.