使用 CasperJS 单击第二个元素

Click on second element with CasperJS

我想使用 CasperJS 单击文档中的第二个元素。

我的文档:

<div class="sample secondClass">1</div>
<div class="sample">2
  <ul class="ul">
    <li class="li">
      <a class="link">
        <div class="div_msg">
          <span>AbCde</span>
        </div>    
      </a>
    </li>
  </ul>
<div class="sample secondClass">3</div>

这是我试过的:

casper.thenClick(x('//*[@class="sample"][2]/ul[@class="ul"]/li[@class="li"]/a[@class="link"]/div[@class="div_msg"]/span[string-length(text())="ABCDE"]'), function() {
  ...
  //do anythings
  ...
}

x(...) 是一个方便的函数,可以将 XPath 表达式与几乎所有 CasperJS 函数一起使用,而不是 CSS select 或。 :nth-child(1) 是 CSS select 或者,它在 XPath 表达式中不起作用。

您可以 select 一个元素在其匹配兄弟姐妹中的位置 [x]。如果你想要第二个元素,那么使用 x('//*[@class="sample"][2]') (XPaths 和 CSS select 或者是 1-indexed 而不是像基本上所有其他编程语言一样的 0-index。

colorMatchingRed('//*[@class="sample"][2]')

function colorMatchingRed(xpath) { 
    var spans = document.evaluate(xpath, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); 
    for (var i = 0 ; i < spans.snapshotLength; i++ ) spans.snapshotItem(i).style.color = "red";
}
<div>
    <div class="sample">No</div>
    <div class="sample">Yes</div>
    <div class="sample">No</div>
</div>
<hr/>
<div>
    <div>No</div>
    <div class="sample">No</div>
    <div class="sample">Yes</div>
    <div class="sample">No</div>
</div>

您还可以使用 x('//*[@class="sample" and position()=2]'),它的含义略有不同,因为它匹配其兄弟元素中的第二个元素,该元素也具有特定的 @class 属性。

colorMatchingRed('//*/*[@class="sample" and position()=2]')

function colorMatchingRed(xpath) { 
    var spans = document.evaluate(xpath, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); 
    for (var i = 0 ; i < spans.snapshotLength; i++ ) spans.snapshotItem(i).style.color = "red";
}
<div>
    <div class="sample">No</div>
    <div class="sample">Yes</div>
    <div class="sample">No</div>
</div>
<hr/>
<div>
    <div>No</div>
    <div class="sample">Yes</div>
    <div class="sample">No</div>
    <div class="sample">No</div>
</div>

如果元素不是彼此的兄弟姐妹,那么您还可以评估节点集和select该集合中的特定元素:x('(//*[@class="sample"])[2]')。它创建一组具有特定 @class 的所有元素并选择第二个。

colorMatchingRed('(//*[@class="sample"])[2]')

function colorMatchingRed(xpath) { 
    var spans = document.evaluate(xpath, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); 
    for (var i = 0 ; i < spans.snapshotLength; i++ ) spans.snapshotItem(i).style.color = "red";
}
<div>
    <div class="sample">No</div>
    <div class="sample">Yes</div>
    <div class="sample">No</div>
</div>
<hr/>
<div>
    <div>No</div>
    <div class="sample">No</div>
    <div class="sample">No</div>
    <div class="sample">No</div>
</div>


这是更新问题的正确点击调用:

casper.thenClick(x('//*[@class="sample"][2]/ul[@class="ul"]/li[@class="li"]/a[@class="link"]/div[@class="div_msg"]/span[string-length(text())=string-length("ABCDE")]'), ...)

或更短:

casper.thenClick(x('//*[@class="sample"][2]//div[@class="div_msg"]/span[string-length(text())=string-length("ABCDE")]'), ...)