Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PhantomJS open one page after another

I used this example to create a phantomjs code to login to website.

var page = require('webpage').create();
page.open("http://www.facebook.com/login.php", function(status) {

  if (status === "success") {
    page.onConsoleMessage = function(msg, lineNum, sourceId) {
      console.log('CONSOLE: ' + msg + ' (from line #' + lineNum + ' in "' + sourceId + '")');
    };
    page.evaluate(function() {
      console.log('hello');
      document.getElementById("email").value = "email";
      document.getElementById("pass").value = "password";
      document.getElementById("u_0_1").click();
      // page is redirecting.
    });
    setTimeout(function() {
      page.evaluate(function() {
        console.log('haha');
      });
      page.render("page.png");
      phantom.exit();
    }, 5000);
  }
});

From this link. https://gist.github.com/ecin/2473860

But I want to open another link from a button or go directly on it. How can I do it?

Here is a simpler example. Doesn't work...

var page = require('webpage').create();
var url = "www.example.com";

page.open(url, function (status) {

    setTimeout(function () {
        page.evaluate(function () {
            console.log('haha');
        });
        page.render("example.png");
        phantom.exit();
    }, 5000);

});



var url = "www.google.com";

page.open(url, function (status) {

    setTimeout(function () {
        page.evaluate(function () {
            console.log('haha');
        });
        page.render("google.png");
        phantom.exit();
    }, 5000);

});
like image 248
macroscripts Avatar asked Jun 20 '15 13:06

macroscripts


1 Answers

Very close, now combine your two snippets into one. page.open() is asynchronous which is why you need to open the next page only after the first one has finished:

var page = require('webpage').create();
var url = "http://www.example.com";

page.onConsoleMessage = function(msg, lineNum, sourceId) {
    console.log('CONSOLE: ' + msg + ' (from line #' + lineNum + ' in "' + sourceId + '")');
};

page.open(url, function (status) {
    page.onConsoleMessage = function(msg, lineNum, sourceId) {
        console.log('CONSOLE: ' + msg + ' (from line #' + lineNum + ' in "' + sourceId + '")');
    };
    page.evaluate(function() {
        document.getElementById("email").value = "email";
        document.getElementById("pass").value = "password";
        document.getElementById("u_0_1").click();
        // page is redirecting.
    });

    setTimeout(function () {
        page.evaluate(function () {
            console.log('haha');
        });
        page.render("example.png");


        var url = "http://www.google.com";

        page.open(url, function (status) {
            setTimeout(function () {
                page.evaluate(function () {
                    console.log('haha');
                });
                page.render("google.png");
                phantom.exit();
            }, 5000);
        });
    }, 5000);
});

To actually see the console.log() inside of page.evaluate() you will need to register to the page.onConsoleMessage event. There are more other events that are helpful when debugging.

Don't forget to add the protocol (http:// or file:///) to the URLs that you're opening. PhantomJS is a bit picky in that regard.

Instead of waiting a static amount of time (setTimeout()) until the next page is loaded after you do some action. You should make use of the page.onLoadFinished event. This is rather cumbersome to get right for navigation intensive scripts. Use CasperJS for longer scripts.

Oftentimes Element.click() doesn't work. This question has many solutions for those cases.

like image 144
Artjom B. Avatar answered Nov 06 '22 00:11

Artjom B.