使用 CasperJS 的 getElementByXPath 根据变量在页面上查找元素

Find an element on the page based on a variable using CasperJS' getElementByXPath

我在使用带有可变 xpath 参数的 __utils__.getElementByXPath() 时遇到问题,请参见示例:

licid 在脚本的 cli 执行时作为 argv (--licid=FAT32) 给出,并被 CasperJS 正确确认。

casper.then(function() {
    var xpath_lic = '//*[contains(text(), "' + casper.cli.get("licid") + '")]';
    this.echo('searching for...' + xpath_lic);
    var found = this.evaluate(function() {
        return __utils__.getElementByXPath(xpath_lic);
    });
    if (found) {
        this.echo('Lic found');
    }
    else {
        this.echo('Lic not found');
    }
});

上面的代码总是打印出来"Lic not found"! 但是当我将 return 行更改为:

return __utils__.getElementByXPath('//*[contains(text(), "FAT32")]');

这会给我 "Lic found" 这是正确的!

如何使用 __utils__.getElementByXPath() 中的 licid 使行更通用?

casper.evaluate() is the sandboxed page context (derived from PhantomJS' page.evaluate())。它无权访问在其外部定义的变量。你必须明确地传递它们:

var xpath_lic = '//*[contains(text(), "' + casper.cli.get("licid") + '")]';
var found = this.evaluate(function(xp) {
    return !!__utils__.getElementByXPath(xp); // convert to boolean with `!!`
}, xpath_lic);

您不能将 DOM 节点传递到页面上下文之外,因此您需要像 element.textContent 那样获得它们的表示,或者完全在页面上下文中工作。

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!