Red Cricket Red Cricket - 5 months ago 23
Javascript Question

Why is my PhantomJS script hanging?

I am new to PhantomJS and just know enough javascript to make a mess.

Here is my script ...

"use strict";
var page = require('webpage').create();

page.onConsoleMessage = function(msg) { console.log(msg); };

page.open("https://developer.amazon.com/home.html", function(status) {
if (status === "success") {
console.log("SUCCESS");
var title = page.evaluate(function() { return document.title;});
console.log( title );
var forms = page.evaluate(function() { return document.forms;});
console.log( forms.length );
var num_elements = page.evaluate(function() {return document.forms[0].elements.length;});
console.log( num_elements );
// for each ( var e in document.forms[0].elements ) {
// console.log( "e.name = [" + e.name + " e.value = [" + e.value + "]" );
// }
for ( var i=0; i < document.forms[0].elements.length; i++ ) {
console.log( "name = [" + document.forms[0].elements[i].name + "]" );
}
} else {
phantom.exit(1);
}
phantom.exit(0);
});


When I run it I get this output and then the script seems to hang:

SUCCESS
Amazon.com Sign In
1
18


I don't think I have any typos and don't understand why my loop is not working.

Thanks

Update:

Thanks to Deryck's help I have modified my script to this:

"use strict";
var page = require('webpage').create();

page.onConsoleMessage = function(msg) { console.log(msg); };

page.open("https://developer.amazon.com/home.html", function(status) {
if (status === "success") {
console.log("SUCCESS");
var title = page.evaluate(function() { return document.title;});
console.log( title );
var forms = page.evaluate(function() { return document.forms;});
console.log( forms.length );
var num_elements = page.evaluate(function() {return document.forms[0].elements.length;});
console.log( num_elements );
// for each ( var e in document.forms[0].elements ) {
// console.log( "e.name = [" + e.name + " e.value = [" + e.value + "]" );
// }
for ( var i=0; i < num_elements; i++ ) {
console.log( i );
console.log( "name = [" +
page.evaluate(
function() {
return document.forms[0].elements[i].name
}
)
+ "]" );
}
} else {
phantom.exit(1);
}
phantom.exit(0);
});


But I am getting this error ...

SUCCESS
Amazon.com Sign In
1
18
0
ReferenceError: Can't find variable: i

undefined:2
:3
name = [null]

Answer

The function you pass to page.evaluate will not have access to the variables present in the phantom script; that's because the function code is passed to the page, then evaluated.

Use this form of page.evaluate to pass i:

console.log( "name = [" +
  page.evaluate(function(i) {
    return document.forms[0].elements[i].name;
  }, i)
+ "]");