Selenium ChromeDriver:增加获取Anchor元素值的时间

时间:2018-05-09 20:54:37

标签: selenium selenium-webdriver selenium-chromedriver

这实际上是previous question的延续,但由于问题很长,并且已经给出了赏金的答案,我担心它不会得到任何关注,即使我把它添加到文本的末尾。 所以,经理们 - 我希望你们能够做出最好的决定,让这个问题成为正确的出版物 - 在这里或者仍然在上一个问题中。

这一次,我在循环锚元素时有越来越多的时间。 也就是说,每次调用func()都需要更多时间。 循环只有5次迭代。

void func(WebElement anchorsElement){

    List<WebElement> anchors = anchorsElement.findElements(By.tagName("a"));

    for (WebElement a : anchors) {

        if (a.getAttribute("class").indexOf("a") > 0)
            values.add("A");
        else if (a.getAttribute("class").indexOf("b") > 0)
            values.add("B");
        else if (a.getAttribute("class").indexOf("c") > 0)
            values.add("C");

    }
}

这次,我对文字不感兴趣,但我需要获得课程名称。这就是为什么我无法使用上一个问题给我的解决方案。

这是anchors元素的一个例子:

<div class="meetings-8 ">
    <a class="Call-bg Call-s glib-tvene-dW1eVj25 glib-thepart-WdKOwxDM-Wtn9Stg0 glib-partnames-alal;Ashkelon" title="[b]Next meeting:[/b]
alal - Ashkelon
13.05.2018">&nbsp;</a>
    <a class="Call-bg a glib-tvene-j1TJiPdn glib-thepart-Wtn9Stg0-2XrRecc3 glib-partnames-Ashkelon;kdkdkdkd" title="[b]991818&amp;nbsp;[/b](Ashkelon - kdkdkdkd)
09.05.2018">&nbsp;</a>
    <a class="Call-bg b glib-tvene-lhJEIDIa glib-thepart-Wtn9Stg0-xxxpBZl2 glib-partnames-Ashkelon;ieieie" title="[b]920032&amp;nbsp;[/b](Ashkelon - ieieie)
06.05.2018">&nbsp;</a>
    <a class="Call-bg a glib-tvene-IBZf2hYI glib-thepart-Cxq57r8g-Wtn9Stg0 glib-partnames-west-ham;Ashkelon" title="[b]882772&amp;nbsp;[/b](mcmcmcmc - Ashkelon)
29.04.2018">&nbsp;</a>
    <a class="Call-bg a glib-tvene-0U3juSVT glib-thepart-Wtn9Stg0-K6xezbY7 glib-partnames-Ashkelon;kKkssks" title="[b]001991&amp;nbsp;[/b](Ashkelon - kKkssks)
22.04.2018">&nbsp;</a>
    <a class="Call-bg Call-bg-last a glib-tvene-ddkDE7Ld glib-thepart-UDg08Ohm-Wtn9Stg0 glib-partnames-kokok;Ashkelon" title="[b]722726&amp;nbsp;[/b](kokok - Ashkelon)
14.04.2018">&nbsp;</a>
</div>

你能帮忙吗?

1 个答案:

答案 0 :(得分:0)

与上一个问题一样,您可以在网页上执行JavaScript,以减少通过电话进行的调用:

var parent = arguments[0];
// ^ JavaScript is executed as a function call.
//   We need to get the parent element passed as an argument.

Array.from(parent.getElementsByTagName('a'))
//         ^ Get all the "a" tags in the parent
// ^ and convert the HTMLCollection to an Array so we can use reduce
.reduce(
// ^ Reduce will call the following callback on each element with an "accumulated" value (your result) and the current element of the array. The first value of the accumulator is the initial value we provide as the second argument
  (acc, anchor) => {
    if (anchor.classList.contains("a")) {
    //        ^ The classList.contains method will check if the anchor has the class "a" applied.
      acc.push("A");
      // ^ Add "A" to the accumulator
    }
    if (anchor.classList.contains("b")) { acc.push("B"); }
    if (anchor.classList.contains("c")) { acc.push("C"); }
    return acc;
    // ^ Return the accumulated value for the next iteration
  },
  [],
  // ^ Initial value of the accumulator
);

简化,JavaScript是:

Array.from(arguments[0].getElementsByTagName('a'))
  .reduce((acc, { classList }) => {
    classList.contains("a") && acc.push("A");
    classList.contains("b") && acc.push("B");
    classList.contains("c") && acc.push("C");
    return acc;
  }, []);

您可以像上一个问题一样打电话:

public ArrayList<?> func(WebElement element)
{
    final String JS_TRANSFORM_ANCHOR_CLASSES_TO_VALUES = 
        "return Array.from(arguments[0].getElementsByTagName('a'))\n" +
        "  .reduce((acc, { classList }) => {\n"
        "    classList.contains(\"a\") && acc.push(\"A\");\n"
        "    classList.contains(\"b\") && acc.push(\"B\");\n"
        "    classList.contains(\"c\") && acc.push(\"C\");\n"
        "    return acc;\n"
        "  }, []);\n"

    WebDriver driver = ((RemoteWebElement)table).getWrappedDriver();
    Object result = ((JavascriptExecutor)driver).executeScript(JS_TRANSFORM_ANCHOR_CLASSES_TO_VALUES, element);
    return (ArrayList<?>)result;
}