`querySelectorAll`在`casperjs`

时间:2018-01-14 10:34:36

标签: javascript casperjs

使用casperjs,我知道我可以使用this.evaluate在访问过的网页的上下文中执行JavaScript。它似乎运作良好,但无论起始网址是什么,我都无法找到document.querySelectordocument.querySelectorAll的任何内容。

为了解决这个问题,我创建了两个文件:test.htmltest.js,在端口python3 -m http.server上本地提供8000。这些是文件:

的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秒钟让页面加载,没有任何结果。< / p>

使用grabParagraphs修改document.getElementsByTagName也不起作用。我无法弄清楚问题是什么,我能找到的每个例子都展示了querySelector的用法,所以它应该有效。

我在phantomjs 2.1.1上使用casperjs 1.1.4Linux Mint

修改

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

grabParagraphs

最初我假设我可以将结果推送到变量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的上下文中定义的,因此它是全局可用的。但是,它在页面的上下文中不可用,所以这就是问题!

1 个答案:

答案 0 :(得分:1)

您没有从grabParagraphs函数中的evaluate返回值。

在浏览器上下文中创建另一个数组变量,将该数组返回给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();
});

希望有所帮助!