这是一个棘手的问题。
我对javascript非常熟悉,但我正在使用PhantomJS和CasperJS自动抓取网站的项目。这对我来说是全新的主题。
我能够弄清楚如何使用Casper并导航,登录到页面等,但是它通常不流畅,因为一般流程似乎是:
casper.start('http://google.fr/');
casper.then(function() {
this.echo("I'm in your google.");
});
casper.then(function() {
this.echo('Now, let me write something');
});
casper.then(function() {
this.echo('Oh well.');
});
casper.run();
我的问题在于我想在网站上做各种各样的事情,具体取决于获得的数据。我不能预先布局导航序列而不是改变它。我希望这是有道理的。
为了解决这个问题,我创建了一个带内置函数的Javascript Navigator对象。我的一般概念是:
navigator.logIn(function()
{
navigator.actionA(parameters, function()
{
if (navigator.data.a == navigator.data.b) {
navigator.actionB();
} else {
navigator.actionC();
}
});
});
并且嵌入在这些函数中的每一个都是casper函数。
以下是我的实际代码的缩短版本,以及事情开始变得时髦的地方:
var casper = require('casper').create({
clientScripts: [ 'jquery.min.js' ],
onError: function(self, m) {
console.log('FATAL:' + m);
self.exit();
},
});
var navigator = new _Navigator();
function _Navigator() { }
_Navigator.prototype.logIn = function(aCallback)
{
var self = this;
casper.start('https://website/login.asp', function()
{
if (1 == 1) {
this.evaluate(function() {
$("input[name=blah]").val('blahblah');
});
// ... A LOT MORE CODE
aCallback();
}
});
}
_Navigator.prototype.search = function(aDataSet, aCallback)
{
var self = this;
console.log('this works');
casper.then(function(){
console.log('this works');
});
var firstName = 'foobar';
casper.then(function(){
console.log('this works');
this.evaluate(function()
{
console.log('this no longer works!!');
$('input[id=blah]').val(firstName);
aCallback();
});
});
}
navigator.logIn(function() {
// LOG IN RUNS, AND CALLS BACK SUCCESSFULLY...
navigator.search({'dataset'}, function()
{
console.log('This never runs');
});
});
casper.run();
你会注意到在navigator.login函数中,我调用了casper.start();在这里,评估函数工作正常,然后我在casper.start()中执行回调函数;在我的回调中,我调用了下一个函数navigator.search,我认为它仍然在casper.start中实际执行?
当我尝试在第一个回调函数调用的这个新函数中运行casper.evaluate时,一切似乎表现都很好,但casper.evaluate不再有效!它似乎吃了这个功能,没有打印任何控制台日志或任何东西。
我已经尝试了一切。我不确定如何正确地做到这一点。有没有人对我做错了什么有任何建议?感谢。
答案 0 :(得分:4)
我知道这已经很老了,但是:这里发生的是两个问题的组合:
casper.evaluate()
似乎吃掉了当前堆栈中的所有错误 - onError
不会从.evaluate()
回调中运行。
.evaluate
中使用的函数是 not 标准闭包 - 它们是沙盒的,并且无法访问其范围之外的变量,除非作为显式参数传递给{{1 }}。因此,在您调用casper.evaluate
的评估函数中,范围内没有aCallback()
,并且函数将以aCallback
失败(静默)。
答案 1 :(得分:0)
casper.evaluate()是无头浏览器会话的窗口。 传递给evaluate的函数中发生的任何事情都不会出现在本地控制台上。 但是,您可以记录从evaluate返回的任何值,也可以通过设置侦听器来打印所有输出:
casper.on('remote.message', function(message) {
console.log(message);
});