我刚开始使用CasperJs,我很难调试它,因为很多编码错误似乎会导致脚本在没有提供错误消息的情况下退出。当您使用详细模式时,您会收到应该获取的消息,直到有问题的代码行,此时它就会退出。
例如,如果我执行代码:
var casper = require('casper').create({
verbose: true,
logLevel: "debug"
});
casper.start('https://www.google.com/#q=stackoverflow', function(){
});
casper.wait(2000, function(){
});
casper.then(function() {
hrefAr = this.evaluate(getLinks);
this.log(hrefAr.length + ' links found', 'info');
this.exit();
});
casper.run(function() {
this.exit();
});
function getLinks() {
var links = document.querySelectorAll('a');
return Array.prototype.map.call(links, function(e) {
return e.getAttribute('href');
});
}
我得到以下结果:
...a bunch of info & debug messages, followed by...
[info] [phantom] Step 4/4 https://www.google.com/search?q=stackoverflow&cad=h (HTTP 200)
[info] [phantom] 89 links found
[debug] [phantom] Navigation requested: url=about:blank, type=Other, lock=true, isMainFrame=true
[debug] [phantom] url changed to "about:blank"
如果我将日志语句添加到函数 getLinks...
...code as shown above...
function getLinks() {
this.log('getLinks ran', 'info');
var links = document.querySelectorAll('a');
...code as shown above...
。这会导致脚本失败,如下所示:
...the same info & debug messages...
[info] [phantom] Step 4/4 https://www.google.com/search?q=stackoverflow&cad=h (HTTP 200)
...NO LOGS, ECHOS, OR RESULTS PAST THIS POINT, JUST THESE TWO CLOSING STATEMENTS...
[debug] [phantom] Navigation requested: url=about:blank, type=Other, lock=true, isMainFrame=true
[debug] [phantom] url changed to "about:blank"
它不会告诉你出了什么问题,它只是让你回到空白并结束执行。
有没有办法获得更好的错误报告?或者任何错误报告?
当我尝试使用以下代码实现以下解决方法时:
var casper = require('casper').create({
verbose: true,
logLevel: "debug"
});
casper.start('https://www.google.com/#q=stackoverflow', function(){
});
casper.wait(2000, function(){
});
casper.then(function() {
reportErrors(function() {
hrefAr = this.evaluate(getLinks);
this.log(hrefAr.length + ' links found', 'info');
this.exit();
});
});
casper.run(function() {
this.exit();
});
function getLinks() {
//this.log('getLinks ran', 'info');
var links = document.querySelectorAll('a');
return Array.prototype.map.call(links, function(e) {
return e.getAttribute('href');
});
}
function reportErrors(f) {
var ret = null;
try {
ret = f();
} catch (e) {
casper.echo("ERROR: " + e);
casper.exit();
}
return ret;
}
我得到...
...info & debug messages shown above...
[info] [phantom] Step 4/4 https://www.google.com/search?q=stackoverflow&cad=h (HTTP 200)
ERROR: TypeError: undefined is not a constructor (evaluating 'this.evaluate(getLinks)')
--THIS IS WHERE MY LINK COUNT WOULD BE REPORTED
[debug] [phantom] Navigation requested: url=about:blank, type=Other, lock=true, isMainFrame=true
[debug] [phantom] url changed to "about:blank"
这有一个开放的PhantomJS问题。
您可以通过用reportErrors
函数包装每个then
和类似内容来绕过它,例如:
function reportErrors(f) {
var ret = null;
try {
ret = f();
} catch (e) {
casper.echo("ERROR: " + e);
casper.exit();
}
return ret;
}
casper.then(function() {
reportErrors(function() {
...
});
});
在修复 PhantomJS 2.x 中的吞噬错误之前,您可以尝试以下几种方法:
-
使用 PhantomJS 1.9.8。底层QtWebKit引擎现在已经有5年多的历史了,但它在大多数时候仍然运行良好。您可以添加命令行选项,例如
--ignore-ssl-errors=true
是否存在 SSL/TLS 问题。CasperJS 支持通过将PHANTOMJS_EXECUTABLE
环境变量设置为要使用的可执行文件或可执行文件的路径,按需更改当前终端会话的 PhantomJS 版本。例如,在Windows上:set PHANTOMJS_EXECUTABLE=phantomjs198
(我将它们编号并在PATH中)。 -
如果是语法错误,你担心,然后先在你的代码上运行一个 linter。我可以推荐eslint和jshint。
-
使用其他事件来检测错误(使用 PhantomJS 1.9.8):
resource.error
、page.error
、remote.message
和casper.page.onResourceTimeout
。例
关于您的特殊功能。 this
在reportErrors
的回调中没有意义。您需要绑定另一个对象:
casper.reportErrors = function (f) {
var ret = null;
try {
ret = f.call(this);
} catch (e) {
this.echo("ERROR: " + e);
this.exit();
}
return ret;
}
然后你可以像以前一样使用它:
casper.then(function() {
this.reportErrors(function() {
hrefAr = this.evaluate(getLinks);
this.log(hrefAr.length + ' links found', 'info');
this.exit();
});
});