`querySelectorAll` 没有 return `casperjs` 中的任何东西

`querySelectorAll` doesn't return anything in `casperjs`

使用 casperjs,我知道我可以使用 this.evaluate 在访问页面的上下文中执行 JavaScript。它似乎运行良好,除了我找不到任何带有 document.querySelectordocument.querySelectorAll 的东西,无论起始 URL 是什么。

为了对此进行调查,我创建了两个文件:test.htmltest.js,在端口 8000 上通过 python3 -m http.server 在本地提供服务。这些是文件:

test.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8"/>
    <title>Page title</title>
</head>
<body>
    <p>A test to see</p>
    <p>if casperjs can grab elements</p>
    <p>evaluating JS</p>
    <p>in the context of the page</p>
</body>
</html>

test.js

function grabTitle(){
    return document.title;
}

function grabParagraphs(){
    var pars = document.querySelectorAll("p");
    for (var i=0; i<pars.length; i++){
        texts.push(pars[i].textContent);
    }
}

var casper = require("casper").create();
var url = "http://localhost:8000/test.html";
var texts = [];

casper.start(url,function(){
    this.echo("Begin");
});

casper.then(function(){
    var title = this.evaluate(grabTitle);
    this.echo("The title is: " + title);
    this.evaluate(grabParagraphs);
    this.echo(texts.length + " paragraphs found:\n" + texts);
});

casper.run(function(){
    this.echo("Done").exit();
});

运行 casperjs test.js 给了我这个输出:

Begin
The title is: Page title
0 paragraphs found:

Done

它找到了标题,所以 grabTitle 工作正常,在页面的上下文中执行,但没有找到段落。我想也许我没有等到页面加载,所以我尝试了 casper.waitForSelector("p",function(){ ... }); 甚至 casper.wait(10000,function ... ),等待 10 秒让页面加载,没有任何结果。

使用 document.getElementsByTagName 修改 grabParagraphs 也不起作用。我不知道是什么问题,我能找到的每个例子都展示了 querySelector 的用法,所以它应该可以工作。

我在 Linux Mint

上使用 phantomjs 2.1.1casperjs 1.1.4

编辑

根据@Mario Nikolaus 的建议,我更改了 test.js:不是将结果推送到 test.js 的全局上下文中定义的数组 texts,现在我定义textsgrabParagraphs 然后 return 结果:

function grabParagraphs(){
    var pars = document.getElementsByTagName("p");
    var texts = [];
    for (var i=0; i<pars.length; i++){
        texts.push(pars[i].textContent);
    }
    return texts;
}

casper.then(function(){
    var title = this.evaluate(grabTitle);
    this.echo("The title is: "+title);
    var texts = this.evaluate(grabParagraphs);
    this.echo(texts.length+" paragraphs found:\n"+texts)
});

最初我假设我可以将结果推送到变量 texts 中,因为它是在 test.js 的上下文中定义的,因此它是全局可用的。但是,它在页面的上下文中不可用,所以这就是问题所在!

您没有在 grabParagraphs 函数中 return 计算值。

在浏览器上下文中创建另一个数组变量,return 该数组给你 casper 上下文并将其分配给数组。

function grabTitle(){
  return document.title;
}

function grabParagraphs(){
  var arr = [];
  var pars = document.querySelectorAll("p");
  for (var i=0; i<pars.length; i++){
      arr.push(pars[i].textContent);
  }
  return arr;
}

var casper = require("casper").create();
var url = "http://localhost:8001/a.html";

casper.start(url,function(){
  this.echo("Begin");
});

casper.then(function(){
  var title = this.evaluate(grabTitle);
  this.echo("The title is: " + title);
  var texts = this.evaluate(grabParagraphs);
  this.echo(texts.length + " paragraphs found:\n" + texts);
});

casper.run(function(){
  this.echo("Done").exit();
});

希望对您有所帮助!