0

I am writing a PhantomJS program that should open a page, track its time and write the loading time in the console. My goal is to make this function run for 5 times.

Problem is that when I write "for" loop which executes only 1 time - function runs correctly, but when I try to run it 2 times, I get the error message that it failed to open the address. It seems that address is not passed second time. I have no idea what could go wrong anymore. This is my code:

var page = require('webpage').create(),
system = require('system'),
t;

//Opening a page and tracking page load time
var loadpage = function (){
    address = 'http://www.google.com';
    t = Date.now();
    page.open(address, function(status) {
        if (status !== 'success') {
            console.log('FAIL to load the address');
        } else {
            t = Date.now() - t;
            console.log('Loading ' + address);
            console.log('Loading time ' + t + ' msec');
        }

        phantom.exit();
    });
};

for (var i = 0; i <2 ; i++) {
    loadpage(i);
}
Artjom B.
  • 61,146
  • 24
  • 125
  • 222
  • How come you call `loadpage(i)` with a parameter but you define that function without parameters `var loadpage = function()` ? – John Pink Oct 20 '15 at 16:21
  • Note that `t` is defined outside the function, and `adress` is a global. Changing `t` in one function call, changes it for every function call, as it's not scoped to the function. – adeneo Oct 20 '15 at 16:22
  • Thanks for your insights! I am new to this, so there is a lot of things I don't know yet. Thanks again! Your answers were very usefull – Gintarė Kaubrytė Oct 22 '15 at 05:40
  • @GintarėKaubrytė Use [@ if you want to reply](http://meta.stackexchange.com/q/43019/266187) to somebody. Otherwise, they won't get a notification if there are two or more people talking in the comments. – Artjom B. Oct 22 '15 at 10:30

2 Answers2

4

page.open() is an asynchronous function. If you call it in a loop, then it the loop will be fully executed before even the first page request is sent. The problem is that calling page.open() multiple times immediately after each other will overwrite the previous invocations. At best, you can only load the last URL.

You either need to wait for each page load or you can create multiple pages in order to request pages in parallel. Also, you should exit (phantom.exit()) PhantomJS only after you've waited for each page load.

Here are some ways to do this:


Easy way to do it:

var loadpage = function (i, max){
    if (i === max) {
        phantom.exit();
        return;
    }
    var address = 'http://www.google.com';
    t = Date.now();
    page.open(address, function(status) {
        if (status !== 'success') {
            console.log('FAIL to load the address');
        } else {
            t = Date.now() - t;
            console.log('Loading ' + address);
            console.log('Loading time ' + t + ' msec');

        }

        loadpage(i+1, max)
    });
};

loadpage(0, 5);
Community
  • 1
  • 1
Artjom B.
  • 61,146
  • 24
  • 125
  • 222
1

It seems you shouldn't call phantom.exit() halfway through your program.

djechlin
  • 59,258
  • 35
  • 162
  • 290
  • That is correct, it should've been `phantom.close()` to close the page and release the memory, not `exit` which exits the program. – adeneo Oct 20 '15 at 16:23
  • @adeneo That's not exactly true. The `page` cannot be used after it is closed. If a `page` is closed, then a new page must be created for the next URL. – Artjom B. Oct 20 '15 at 16:36
  • @ArtjomB. - and that's what the `loadpage` function does – adeneo Oct 20 '15 at 16:54
  • 1
    @adeneo No, it doesn't, because `page = require('webpage').create()` is outside of `loadpage()`. Also, `phantom.exit()` needs to be called at some point. Otherwise, PhantomJS will just hang there. – Artjom B. Oct 20 '15 at 17:05
  • @ArtjomB.- well okay, the `.create()` call should've been inside the function, but I think the OP intended to create a new instance on each function call, and then close that instance once the page has loaded. – adeneo Oct 20 '15 at 17:53
  • Thanks for your insights! I am new to this, so there is a lot of things I don't know yet. Thanks again! Your answers were very usefull – Gintarė Kaubrytė Oct 22 '15 at 05:40