【问题标题】:`querySelectorAll` doesn't return anything in `casperjs``querySelectorAll` 在 `casperjs` 中不返回任何内容
【发布时间】:2018-01-14 10:34:35
【问题描述】:

使用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,现在我在grabParagraphs 中定义texts 和然后返回结果:

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 的上下文中定义的,因此它是全局可用的。但是,它在页面上下文中不可用,所以这就是问题所在!

【问题讨论】:

    标签: javascript casperjs


    【解决方案1】:

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

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

    希望有帮助!

    【讨论】:

    • 宾果游戏!这就是问题所在,我认为texts 可以在页面上下文“内部”使用,真是个愚蠢的错误
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-27
    • 2019-04-06
    • 2012-02-15
    • 2020-09-07
    • 2021-11-22
    相关资源
    最近更新 更多