1

我是 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();
4

4 回答 4

7

您必须调用依赖于documentwith 的函数this.evaluate

var paragraph = this.evaluate(function() {
    return document.querySelector('p').innerHtml;
});

如有疑问,请查阅文档

于 2013-08-20T06:35:12.420 回答
3

CasperJS 从 PhantomJS 继承了 DOM 上下文(页面上下文)和外部上下文之间的拆分。您只能通过casper.evaluate(). document回调内部evaluate()是您在普通 JavaScript 中所期望的变量,但还有一个document外部evaluate()只是一个虚拟对象,不提供对页面 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()

另外,请查看了解 CasperJS 中的评估函数

于 2016-01-07T09:47:00.070 回答
0

尝试this.echo(this.fetchText('p'));获取innerhtml。参考文档

于 2015-04-25T11:48:38.787 回答
0

this.getTitle() 在 Casper 对象上执行 getTitle() 函数并在 Casper 上下文中运行,因此它会产生预期的结果。

但是,“文档”在 Casper 上下文中不可用。根本原因是 Casper 正在运行 PhantomJS,这是一个 Web 浏览器。因此,“文档”仅在浏览器中可用,它比在 Casper 上下文中运行的代码“更深”一层。没有直接的方法可以在两个环境之间共享变量,但是有一种方法可以通过复制值将它们作为参数传递。

两种环境(Casper 和 Phantom)之间的“桥梁”是 Casper 的“评估”功能。函数内部的所有内容,作为参数传递给“评估”,都将在浏览器上下文中执行,而不是在 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 端获取。IE

var result = casper.evaluate(function run_in_browser(){
    return document.title;
});
于 2013-10-03T14:21:29.473 回答