10

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);

});
Artjom B.
  • 61,146
  • 24
  • 125
  • 222
edinvnode
  • 3,497
  • 7
  • 30
  • 53
  • Note than PhantomJS has a different execution environment than node. There are bridges between node and PhantomJS, but they are written slightly different. – Artjom B. Jun 20 '15 at 13:14

1 Answers1

9

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.

Community
  • 1
  • 1
Artjom B.
  • 61,146
  • 24
  • 125
  • 222
  • 1
    Ok. This has worked but what if I want to enter something in google search box and press button to search. Then I get rendered search results? – edinvnode Jun 20 '15 at 14:28
  • 1
    @macroscripts Google is a really bad site to start experimenting with PhantomJS. But you would use `page.evaluate()` to change the value of an input field and [click](http://stackoverflow.com/questions/15739263/phantomjs-click-an-element) the search button. You can also use `page.sendEvent()` to fill the field and hope that instant results are enabled for PhantomJS. – Artjom B. Jun 20 '15 at 14:59
  • I am using google as an example. I am doing this code on website. It has different domains. I have to login from sub1.domain.com and get access to sub2.domain.com . I want to get some data from it. The code you gave me works but not fully. It gets to sub1 but doesn't login properly. And it goes to sub2 but I don't see my username logged in. I'll paste the example I used later. – edinvnode Jun 20 '15 at 15:25
  • Make it a new question if you have a problem with that. Also, please register to the `resource.error`, `page.error`, `remote.message` and `casper.page.onResourceTimeout` events ([Example](https://gist.github.com/artjomb/4cf43d16ce50d8674fdf)). Maybe there are errors. – Artjom B. Jun 20 '15 at 15:27
  • I asked here: http://stackoverflow.com/questions/30959899/phantomjs-login-after-another-login – edinvnode Jun 20 '15 at 23:37
  • I guess I wasn't clear enough where the second script must be inserted into the first one. You still have to wait a little after clicking. That should answer your linked question. – Artjom B. Jun 21 '15 at 12:47
  • You mean this line document.querySelectorAll("input[value='Sign In']")[0].click(); So how do I insert the waiting time? – edinvnode Jun 21 '15 at 12:50
  • You already do that with the `setTimeout()` call in the first script. You only need to insert the second script into the `setTimeout()` callback. Please look at the answer diff. – Artjom B. Jun 21 '15 at 12:53
  • I did use setTimeout in second script... twice – edinvnode Jun 21 '15 at 12:59
  • @ArtjomB. would you please take a look on my question http://stackoverflow.com/questions/40171792/generate-har-file-from-array-of-links-using-phantomjs ? I really need some help to implement your solution... Thanks! – Valip Oct 21 '16 at 10:04
  • How would this solution change if, instead of calling another site (in this case www.google.com) as the second page, the same page is reloaded using `svgDocument.location.reload();`? Thank you. – casaout Oct 06 '18 at 00:44