我是CasperJS的新手。 this.echo(this.getTitle());
如何运作,但console.log("Page Title ", document.title);
没有?另外为什么我的document.querySelector不工作?有没有人有一个很好的解释?我可以在CasperJS文档中找到答案吗?
这是我的代码:
var casper = require('casper').create();
var url = 'http://www.example.com/';
casper.start(url, function() {
this.echo(this.getTitle()); // works
this.echo(this.getCurrentUrl()); // works
});
casper.then(function(){
this.echo(this.getCurrentUrl()); // works
console.log("this is URL: ", document.URL); // doesn't work
console.log("Page Title ", document.title); // doesn't work
var paragraph = document.querySelectorAll('p')[0].innerHTML;
console.log(paragraph); // doesn't work
});
casper.run();
修改 我现在正在使用casper.thenEvaluate和casper.evaluate,它仍然无法正常工作。有什么想法吗?
var casper = require('casper').create();
var url = 'http://www.example.com/';
casper.start(url, function() {
this.echo(this.getTitle()); // works
this.echo(this.getCurrentUrl()); // works
console.log('page loaded: '); // works
});
casper.thenEvaluate(function(){
var paragraph = document.querySelectorAll('p')[0].innerHTML; // doesn't work
console.log(paragraph); // doesn't work
console.log("Page Title ", document.title); // doesn't work
});
casper.run();
答案 0 :(得分:7)
您必须使用document
调用依赖this.evaluate
的函数:
var paragraph = this.evaluate(function() {
return document.querySelector('p').innerHtml;
});
如有疑问,请咨询the docs。
答案 1 :(得分:3)
CasperJS继承了DOM上下文(页面上下文)与PhantomJS外部上下文之间的分离。您只能通过casper.evaluate()
访问沙盒DOM上下文。 document
回调中的evaluate()
是您在普通JavaScript中所期望的变量,但在document
之外还有一个evaluate()
,它只是一个虚拟对象而且不是#39; t提供对页面DOM的访问。
如果要访问DOM属性,则需要使用evaluate()
。
var title = casper.evaluate(function(){
return document.title;
});
但是这对DOM节点不起作用,因为只有原始对象可以传递出DOM上下文。 PhantomJS文档说明如下:
注意:
evaluate
函数的参数和返回值必须是一个简单的原始对象。经验法则:如果它可以通过JSON序列化,那就没关系了。闭包,函数,DOM节点等将不工作!
如果你想使用document.querySelector()
,那么你需要生成一个可以传递到外面的DOM节点的表示:
var form = casper.evaluate(function() {
var f = document.querySelector('form');
return { html: f.innerHTML, action: f.action };
});
casper.echo(JSON.stringify(form, undefined, 4));
您还可以使用所有可用的CasperJS函数来提供DOM节点的表示,例如casper.getElementsInfo()。
答案 2 :(得分:0)
this.getTitle()在Casper对象上执行getTitle()函数并在Casper上下文中运行,因此它会产生预期的结果。
但是,“文档”在Casper上下文中不可用。根本原因是Casper正在运行PhantomJS,这是一个Web浏览器。因此,'document'仅在浏览器中可用,它比Casper上下文中运行的代码“更深”。在两个环境之间没有直接的共享变量的方法,但有一种方法可以通过复制值将它们作为参数传递。
两个环境(Casper和Phantom)之间的“桥梁”是Casper的“评估”功能。函数内部的所有内容(作为参数传递给'evaluate')都将在浏览器上下文中执行,而不是在Casper上下文中执行。这是一个重要的区别。如Blender所述,此处提供了文档:
http://docs.casperjs.org/en/latest/modules/casper.html#evaluate
以下示例:
casper.evaluate(function(username, password) {
document.querySelector('#username').value = username;
document.querySelector('#password').value = password;
document.querySelector('#submit').click();
}, 'sheldon.cooper', 'b4z1ng4');
在给定的示例中,您可以看到如何将“用户名”和“密码”参数从Casper环境传递到浏览器(页面)环境。
匿名“功能(用户名,密码)”将在浏览器中执行。因此,您可以在其中使用“文档”。
您也可以将值传回,可以在Casper端获取。即
var result = casper.evaluate(function run_in_browser(){
return document.title;
});
答案 3 :(得分:0)
尝试this.echo(this.fetchText('p'));
获取innerhtml。 Refer documentation