在 CasperJS 中使用 __utils__.getElementsByXPath 查找元素

Finding elements using __utils__.getElementsByXPath in CasperJS

下面给出了我的 casper.js 测试脚本的一个片段;

var refObject = undefined;

casper.then(function() {
  refObject = this.evaluate(function() {
    return __utils__.getElementsByXPath('//div[contains(concat(" ", @class, " "), " refObject ")]//a[contains(normalize-space(text()), normalize-space("SampleTest"))]//../../../..');
  });
  require('utils').dump(refObject);
  this.echo(refObject);
  test.assertTruthy(refObject);
});

在评估函数中,我试图获取对 html 元素的引用,如下所示;

<div class="refObject">
    <div class="accordion-heading">
        <div class="accordion-toggle">
            <div class="btn-group">
                <a class="dropdown-toggle" data-toggle="dropdown">SampleTest</a>
            </div>
        </div>
    </div>
</div>

在GoogleChrome(Ctrl+F)中,我测试了xpath,发现引用正确。但是当我执行 casperjs 脚本时,我得到 require('utils').dump(eobject) 作为 []this.echo(eobject) 作为空白的输出。有没有人知道可能是什么问题?

这是 PhantomJS 的问题。您不能将 DOM 元素从页面上下文传递到外部。你必须有一些原始的表示。

Note: The arguments and the return value to the evaluate function must be a simple primitive object. The rule of thumb: if it can be serialized via JSON, then it is fine.

Closures, functions, DOM nodes, etc. will not work!

您可以通过返回数组的长度而不是实际列表来检查这是否是问题所在。

另一个问题可能是匹配 a 元素后的子搜索。使用

normalize-space("SampleTest"))]/../
-------------------------------^

而不是

normalize-space("SampleTest"))]//../

您的 XPath 表达式不必要地复杂,甚至可能容易出错。这个可能更好:

//div[contains(concat(" ", @class, " "), " refObject ") and .//a[contains(text(), "SampleTest")]]