可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I am a PhantomJs newbie. Just checked a similar post on this site. My question is why 'foo' is not logged to console or printed?
var page = require('webpage').create() var foo = 42; function evaluate(page, func) { var args = [].slice.call(arguments, 2); var fn = "function() { return (" + func.toString() + ").apply(this, " + JSON.stringify(args) + ");}"; return page.evaluate(fn); } page.open('http://google.com', function() { var foo = 42; evaluate(page, function(foo) { console.log(foo); },foo); });
回答1:
The call page.evaluate() runs your evaluated code in a sandbox. The sandbox's console is not the same as PhantomJS's console.
The following lines added to your script will print your page's console to stderr.
var system = require('system'); page.onConsoleMessage = function(msg) { system.stderr.writeLine('console: ' + msg); };
A more complete implementation would be:
var page = require('webpage').create() var system = require('system'); var foo = 42; page.onConsoleMessage = function(msg) { system.stderr.writeLine( 'console: ' + msg ); }; function evaluate(page, func) { var args = [].slice.call(arguments, 2); var fn = "function() { return (" + func.toString() + ").apply(this, " + JSON.stringify(args) + ");}"; return page.evaluate(fn); } page.open( 'http://google.com', function() { var foo = 42; evaluate( page, function(foo) { console.log(foo); }, foo ); console.log( "Done" ); phantom.exit( 0 ); // must exit somewhere in the script } );
Outputs:
$ phantomjs /tmp/idiot.js console: 42 Done
By the way, you can call page.open using "about:blank" as your URL if you just want to sandbox test the evaluate function.
回答2:
Output to standard error did not work for me
a work around is assigning :
window.console.log = function(msg) { alert(msg) };
inside the page.evaluate
Then use :
page.onAlert = function(msg) { console.log(msg); };
to catch the alert
回答3:
There were some problems in the past with console logging, but with the current version on phantomjs (1.9.8), you can do:
page.onConsoleMessage = function (msg) { console.log(msg); };
then fire away your console.log
s in the evaluate
's callback:
page.evaluate(function() { console.log("some logged message"); });
回答4:
I'm using phantomjs to automate some Google Closure tests and ran into an issue I needed to debug. I was able to dispatch custom events from my test page and receive them inside page.evaluate
.
File to log messages:
function logger(msg) { var evt = document.createEvent('CustomEvent'); // MUST be 'CustomEvent' evt.initCustomEvent('logger', false, false, msg); document.dispatchEvent(evt); } logger('my debug message');
Phantomjs file. Here I'm using a saveMessage
method to store the string, but you can make that something more appropriate to your needs.
var exec = page.evaluate(function () { window.phantomRunner = new window.goog.testing.TestRunner(); window.phantomTest = new window.goog.testing.TestCase(); // Listen for `logger` events. The message is stored inside the event's detail property. document.addEventListener('logger', function(e) { window.phantomTest.saveMessage(e.detail); }); window.phantomTest.autoDiscoverTests(); window.phantomRunner.initialize(window.phantomTest); window.phantomRunner.execute(); return (window.phantomTest.result_.messages); })
回答5:
Make sure your phantomjs setting does not disable executing javascript
page.settings.javascriptEnabled = true;