使用CasperJS遍历querySelectorAll返回的NodeList

3
我希望遍历来自querySelectorAll的NodeList。 无效的代码
var nodelist = this.evaluate(function() {
    return document.querySelectorAll('tr.firstrow');
});

this.echo("nodelist.length=" + nodelist.length);

for (var i=0; i<nodelist.length; i++) {
    this.echo("i=" + i);
    line = nodelist[i];
    this.echo("Line: " + line.innerText);
}

我得到的是这样的结果:
nodelist.length=3
i=0
this it the first line 
i=1

在 i=1 之后,输出就卡住了。对于第一个项目,“for”循环按预期运行,但是之后它就不再继续了。当我在浏览器控制台中运行 querySelectorAll 时,我能看到所有三个不同的项目。
这里我找到了一种行之有效的方法: 行之有效
var nodelist = this.evaluate(function() {
    var nodes = document.querySelectorAll('tr.firstrow');
    var array = [nodes[0].innerText,nodes[1].innerText,nodes[2].innerText];
    return array;
});
this.echo("nodelist.length=" + nodelist.length);
for (var i=0; i<nodelist.length; i++) {
    this.echo("i=" + i);
    line = nodelist[i];
    this.echo("Line: " + line);
}

但这很不方便。

然后我尝试将此节点列表转换为数组。但这种方法也不起作用,因为从 evaluate 函数返回的值丢失了。

不起作用

var nodelist=this.evaluate(function() 
{
console.log("...evaluate()");
var fr_n=document.querySelectorAll('tr.firstrow');
console.log("fr_n.length:" + fr_n.length);

var fr_a=Array.prototype.slice.call(fr_n);

console.log("fr_a.length:" + fr_a.length);
console.log("typeof fr_a:" + typeof fr_a);
console.log("fr_a[0]=" + fr_a[0].innerText);
console.log("fr_a[1]=" + fr_a[1].innerText);
console.log("fr_a[2]=" + fr_a[2].innerText);

return fr_a;

});

this.echo("nodelist.length=" + nodelist.length);

if (Array.isArray(nodelist))
{
 this.echo ("nodelist is array");
}
else
{
 this.echo ("nodelist is not array");
}

for (var i=0; i<nodelist.length; i++)
{
 this.echo("i:" + i);
 line = nodelist[i];
 this.echo("Line: " + line); 
};

产生以下输出:
remote console.log: ...evaluate()
remote console.log: fr_n.length:3
remote console.log: fr_a.length:3
remote console.log: typeof fr_a:object
remote console.log: fr_a[0]=This is the first line I want to see 
remote console.log: fr_a[1]=This is the second line I want to see
remote console.log: fr_a[1]=This is the third line I want to see
nodelist.length=0
nodelist is array
[info] [phantom] Done 4 steps in 6943ms

我希望nodelist.length的值为3而不是0。

抱歉,打错了。我是指 line = nodelist[i]; - Sven Kirsten
2个回答

3
PhantomJS的page.evaluate()函数是沙盒页面上下文。传递的所有内容必须基本上被字符串化和再次解析。

注意: 评估函数的参数和返回值必须是一个简单的原始对象。经验法则: 如果可以通过JSON序列化,那么就可以了。

闭包、函数、DOM节点等都不起作用!

这意味着你不能将元素从页面上下文中取出,但你可以在页面上下文中构建它们的表示,并将其传递到外部。
你可能想要这些元素的textContent。你可以使用CasperJS函数getElementsInfo(),该函数为每个元素提供text属性。然后,你可以仅为此属性过滤信息:
var texts = casper.getElementsInfo('tr.firstrow').map(function(tr){
    return tr.text;
});

如果这不是你想要的文本,你需要找到另一个表示方式或在页面上下文中遍历NodeList(在casper.evaluate()内部)。

0
尝试将由querySelectorAll返回的NodeList转换为Array
var nodelist=this.evaluate(function() {
    return Array.prototype.slice.call(document.querySelectorAll('tr.firstrow'));
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接