在 CasperJS 中单击具有特定 class 的段落中的所有 'a' 元素

Click on all 'a' elements in paragraph with specific class in CasperJS

我有以下问题。 我有这个 HTML 代码的结构:

<p class="description">
    lorem ipsum, bla bla bla 
    <a href="# onclick="somemethod(id)">click</a>
</p>
<p class="description">
    lorem ipsum, bla bla bla
</p>
<p class="description">
    lorem ipsum, bla bla bla 
    <a href="# onclick="somemethod(id)">click</a>
</p>

现在我需要通过 CasperJS 单击 class 'description' 段落中的每个 "a"。

我试试这个:

while (selector = document.querySelector('p.description a')) {
    casper.then(function () {
        this.click(selector);
        console.log('click');
    })
}

但是没用。

是否有任何可能如何做到这一点?

你有两个问题。

  • 您不能同时使用 documentcasper,因为 document 仅在页面上下文 (casper.evaluate()) 内可用,但 casper 在页面上下文中不可用。
  • 您需要完全在页面上下文中或完全在外部迭代可点击元素。

CSS select或

如果所有 <p> 元素都具有相同的父元素,并且中间没有其他元素,那么您可以简单地使用 CSS selectors 来实现:

casper.then(function(){
    var numberOfElements = this.getElementsInfo("p.description").length;
    for(var i = 1; i <= numberOfElements; i++) {
        this.click("p:nth-child("+i+") a");
    }
});

请注意,不可能 select :nth-child 基于 class,因此这也假设没有 "description" 就没有 <p> 元素] class.

XPath 表达式

可以通过使用 XPath 表达式使其更加健壮,因为它们更具表现力。

var x = require("casper").selectXPath;
...
casper.then(function(){
    var numberOfElements = this.getElementsInfo("p.description").length;
    for(var i = 1; i <= numberOfElements; i++) {
        this.click(x("(//p[contains(@class,'description')])["+i+"])/a"));
    }
});

其中 (//p[contains(@class,'description')])["+i+"]) 表示构建了 p 个元素的节点列表 (//p[contains(@class,'description')]),所有元素都包含 "description" 作为其 "class" 属性的一部分。然后例如(nodeList)[3]) select 是该列表中的第三个元素。


如果你想在页面上下文中迭代,那么你需要在页面上下文中使用a click function