Селен (Java) не идентифицирует некоторые элементы в таблице, которая имеет только элементы div - PullRequest
0 голосов
/ 19 июня 2020

Я пытаюсь получить значения из таблицы на веб-странице, содержащей только div элементов. Нет tr td. Ниже приведен пример (не настоящий) того, как выглядит HTML.

<div class="table" style="style="transform: translate3d(0px, 0px, 0px); opacity: 1;">
<div class="row heading">
<div class="row" style="opacity: 1;">
 <div class="cell">
  <div class="row1">value1</div>
  <span class="Tooltip" style="style="position: relative;">...</span>
 </div>
 <div class="cell1">
  <div class="classname"></div>
  <div class="row1">value2</div>
 </div>
 <div class="cell1">
  <div class="classname"></div>
  <div class="row1">value3</div>
 </div>
 <div class="cell1">
  <div class="classname"></div>
  <div class="row1">value4</div>
 </div>
 <div class="cell1">
  <div class="classname"></div>
  <div class="row1">value5</div>
 </div>

В таблице 50 строк по 5 столбцов в каждой. Я попробовал 2 подхода, чтобы получить все значения из таблицы.

  1. Используя CSSSelector

     for(int i=2;i<=38;i++) {
             WebDriverWait wait = new WebDriverWait(driver, 60);
             wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#root > div > div.Home > div.home-left > div.table > div:nth-child("+i+") > div:nth-child(1) > div")));            
             String valueone = driver.findElement(By.cssSelector("#root > div > div.Home > div.home-left > div.table > div:nth-child("+i+") > div:nth-child(1) > div")).getText();
             clist.add(valueone);
             for(int j=2;j<=5;j++) {
                 val = driver.findElement(By.cssSelector("#root > div > div.Home > div.home-left > div.table > div:nth-child("+i+") > div:nth-child("+j+") > div.total")).getText();
                 clist.add(val);
             }   
         }
    
  2. Используя Xpath :

     for(int i=2;i<=38;i++) {
     String c;
         WebDriverWait wait = new WebDriverWait(driver, 30);
         wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[@id=\"root\"]/div/div[3]/div[1]/div[5]/div["+i+"]/div[1]/div")));
         valueone = driver.findElement(By.xpath("//*[@id=\"root\"]/div/div[3]/div[1]/div[5]/div["+i+"]/div[1]/div")).getText();
             clist.add(valueone);
     }
     for(int j=2;j<=38;j++) {
         c = driver.findElement(By.xpath("//*[@id=\"root\"]/div/div[3]/div[1]/div[5]/div["+j+"]/div[2]/div[2]")).getText();
         clist.add(c);
     }   
     for(int k=2;k<=38;k++) {
         c = driver.findElement(By.xpath("//*[@id=\"root\"]/div/div[3]/div[1]/div[5]/div["+k+"]/div[3]/div")).getText();
         clist.add(c);
     }
     for(int l=2;l<=38;l++) {
         c = driver.findElement(By.xpath("//*[@id=\"root\"]/div/div[3]/div[1]/div[5]/div["+l+"]/div[4]/div[2]")).getText();
         clist.add(c);
     }
    

Проблема : когда я пытаюсь выполнить итерацию с использованием селектора css, я получаю это исключение (не удалось найти 12-я строка) -

    Exception in thread "main" org.openqa.selenium.TimeoutException: Expected condition failed: waiting for visibility of element located by By.cssSelector: #root > div > div.Home > div.home-left > div.table > div:nth-child(12) > div:nth-child(1) > div (tried for 30 second(s) with 500 milliseconds interval)
at org.openqa.selenium.support.ui.WebDriverWait.timeoutException(WebDriverWait.java:95)
at org.openqa.selenium.support.ui.FluentWait.until(FluentWait.java:272)
at App.GetData.main(GetData.java:46)
    Caused by: org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"css selector","selector":"#root > div > div.Home > div.home-left > div.table > div:nth-child(12) > div:nth-child(1) > div"}

И когда я пытаюсь выполнить итерацию с использованием X Path, я получаю это исключение (не удалось найти 13-ю строку) -

    Exception in thread "main" org.openqa.selenium.TimeoutException: Expected condition failed: waiting for visibility of element located by By.xpath: //*[@id="root"]/div/div[3]/div[1]/div[5]/div[13]/div[1]/div (tried for 30 second(s) with 500 milliseconds interval)
at org.openqa.selenium.support.ui.WebDriverWait.timeoutException(WebDriverWait.java:95)
at org.openqa.selenium.support.ui.FluentWait.until(FluentWait.java:272)
at App.GetData.main(GetData.java:72)
    Caused by: org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"xpath","selector":"//*[@id="root"]/div/div[3]/div[1]/div[5]/div[13]/div[1]/div"}

Я пробовал ImplicitWait , ExplicitWait и даже Thread.sleep (я знаю, что это не рекомендуется). Кажется, ничего не работает. Ирония в том, что если я попробую 20 раз, Selenium идентифицирует все элементы без проблем за 1 попытку.

  1. Почему селектору css трудно найти element и xpath находит элемент, но ему трудно найти другой элемент?

  2. Я часто сталкивался с этой проблемой в Selenium, когда он может найти тот же элемент без проблем за один прогон и изо всех сил пытается найти его на других трассах? Есть ли постоянное решение / подход к этой проблеме?

Ответы [ 2 ]

1 голос
/ 20 июня 2020

Чтобы получить все значения вместо использования visibilityOfElementLocated(), вам нужно вызвать WebDriverWait для visibilityOfAllElementsLocatedBy(), и вы можете использовать следующую based Locator Strategy :

  • Кодовый блок:

    List<WebElement> values = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath("//div[@class='table']//div[@class='cell' or @class='cell1']/div[@class='row1']")));
    for(WebElement value:values) { System.out.println(value.getText()); }
    

Альтернатива с использованием Java 8 stream() и map()

В качестве альтернативы вы можете использовать Java8 stream() и map() следующим образом:

  • Кодовый блок:

    System.out.println(new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath("//div[@class='table']//div[@class='cell' or @class='cell1']/div[@class='row1']"))).stream().map(element->element.getAttribute("innerHTML")).collect(Collectors.toList()));
    
0 голосов
/ 20 июня 2020

Наконец-то выяснилось, в чем проблема! Я играл с HTML и обнаружил, что при начальной загрузке загружаются только начальные 12 строк (хотя все строки отображаются) и только при дальнейшей прокрутке загружаются остальные строки. То же самое было сделано до обхода строк, и теперь все строки теперь идентифицируются как cssSelector, так и Xpath.

((JavascriptExecutor) driver).executeScript("window.scrollTo(0, document.body.scrollHeight)");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...