Selenium(Java) 无法识别只有 div 元素的 table 中的某些元素
Selenium(Java) not identifying some elements in a table that has only div elements
我正在尝试从只有 div
元素的网页中的 table 获取值。没有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>
table 有 50 行,每行 5 列。我尝试了 2 种方法来从 table.
中获取所有值
使用 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);
}
}
使用 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 路径进行迭代时,出现此异常(找不到第 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 次尝试中毫无问题地识别所有元素。
为什么 css 选择器很难找到一个元素,而 xpath 找到该元素却很难找到另一个元素?
我在 Selenium 中经常遇到这个问题,当它能够在一个 运行 上毫无问题地找到相同的元素而在其他 运行 上很难找到它时?这个问题有永久性的solution/approach吗?
要获取所有值而不是使用 visibilityOfElementLocated()
,您需要引入 for the visibilityOfAllElementsLocatedBy()
and you can use the following xpath based :
代码块:
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()
and 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()));
终于找到问题的原因了!我在玩 HTML 并发现,在初始加载时,只有最初的 12 行被加载(即使显示所有行)并且只有在进一步滚动时,其余行才会被加载。在遍历行之前执行以下操作,现在所有行现在都由 cssSelector
和 Xpath
.
标识
((JavascriptExecutor) driver).executeScript("window.scrollTo(0, document.body.scrollHeight)");
我正在尝试从只有 div
元素的网页中的 table 获取值。没有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>
table 有 50 行,每行 5 列。我尝试了 2 种方法来从 table.
中获取所有值使用 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); } }
使用 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 路径进行迭代时,出现此异常(找不到第 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 次尝试中毫无问题地识别所有元素。
为什么 css 选择器很难找到一个元素,而 xpath 找到该元素却很难找到另一个元素?
我在 Selenium 中经常遇到这个问题,当它能够在一个 运行 上毫无问题地找到相同的元素而在其他 运行 上很难找到它时?这个问题有永久性的solution/approach吗?
要获取所有值而不是使用 visibilityOfElementLocated()
,您需要引入 visibilityOfAllElementsLocatedBy()
and you can use the following xpath based
代码块:
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()
and 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()));
终于找到问题的原因了!我在玩 HTML 并发现,在初始加载时,只有最初的 12 行被加载(即使显示所有行)并且只有在进一步滚动时,其余行才会被加载。在遍历行之前执行以下操作,现在所有行现在都由 cssSelector
和 Xpath
.
((JavascriptExecutor) driver).executeScript("window.scrollTo(0, document.body.scrollHeight)");