【问题标题】:Click on second element with CasperJS使用 CasperJS 单击第二个元素
【发布时间】:2016-04-24 09:50:48
【问题描述】:

我想使用 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
  ...
}

【问题讨论】:

    标签: xpath css-selectors click casperjs


    【解决方案1】:

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

    您可以使用[x] 选择一个元素在其匹配的兄弟元素中的位置。如果您想要第二个元素,请使用x('//*[@class="sample"][2]')(XPath 和 CSS 选择器是 1 索引的,而不是像所有其他编程语言那样的 0 索引)。

    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>

    如果元素不是彼此的兄弟,那么您还可以评估节点集并从该集中选择一个特定元素: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")]'), ...)
    

    【讨论】:

    • 那么标记与您在问题中显示的不同。运行我回答中的示例脚本,看看它们确实有效。
    • 我们以前跳过这个舞。你问了一个严重简化的问题,得到了答案,但事实证明你的问题比这更复杂。您可以编辑您的问题,我们会看看它是否会使我的回答无效。
    • string-length() 产生一个数字,但您将其与字符串进行比较。也许你想使用span[string-length(text())=string-length("ABCDE")]
    • 不,我没有。我已经调查过他们的安全性,但不是那么好。
    • 嗯,这没有帮助吗?
    猜你喜欢
    • 2022-01-02
    • 1970-01-01
    • 1970-01-01
    • 2015-04-25
    • 1970-01-01
    • 1970-01-01
    • 2020-01-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多