循环浏览通过findElements

时间:2017-02-26 20:24:19

标签: java selenium selenium-webdriver

我已经完成了导航到Google,执行搜索以及在第一个结果页面中获取所有结果的标题的任务。

我已将findElements与xpath一起使用,并尝试遍历每个结果并driver.navigate().back()。它抛出StaleElementReferenceException并编写了一个try-catch块并开始初始化catch块中的findElements

在尝试获取findElements的size()时,当我使用隐式等待时,它被确定为9。使用了一个显式的,并且Thread.sleep和size()确实设置为13 - 这正是我所期待的。

当一切顺利时,我可以看到在6到12之后跳过索引。我无法弄清楚是什么。谁能告诉我哪里出错了?谢谢!

以下是我的代码:

 @BeforeClass
    public void setup() {
        driver = LoadWebDriver.getWebDriver();
    }

    @Test(priority=0)
    public void navigateTo() {
        driver.manage().window().maximize();
        driver.get("https://www.google.co.in/");
    }

    @Test(priority=1)
    public void getTheTitles() throws InterruptedException {

        String xPath = "//h3/a";
        int a = 0;
        boolean loopThru = true;
        driver.findElement(By.id("lst-ib")).sendKeys("Java",Keys.ENTER);
//        WebDriverWait wait =  new WebDriverWait(driver, 10);
//        wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.xpath(xPath)));
//        Thread.sleep(3000);
        driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
        List<WebElement> dan = driver.findElements(By.xpath(xPath));
        System.out.println("** The fucking size is "+dan.size()+" **");
        while(loopThru) {
            try {
                dan = driver.findElements(By.xpath(xPath));
                for (int i = a; i < dan.size(); i++) {
                    if(i==dan.size()-1){
                        loopThru=false;
                    }
                    dan.get(a).click();
                    String theTitle = driver.getTitle();
                    System.out.println(a+" "+theTitle);
                    driver.navigate().back();
                }

            }

            catch(Exception e) {
                a++;
                dan = driver.findElements(By.xpath(xPath));
                loopThru = true;

            }
        }
    }



    @AfterClass
    public void tearDown() {

               driver.close();
    }

1 个答案:

答案 0 :(得分:0)

正如您所指出的那样,通过点击其中一个链接导航离开搜索结果页面,以后无法再次使用该特定页面的WebElement引用。因此,当您返回搜索结果页面时,您必须再次find这些链接才能点击它们。

以下是我将如何做到这一点(大致基于您的初始代码):

driver.get("http://www.google.com");

driver.findElement(By.id("lst-ib")).sendKeys("Java" + Keys.ENTER);

int size = new WebDriverWait(driver, 5).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath("//h3/a"))).size();

System.out.println(size + " links");

for (int idx = 0; idx < size; idx++) {
    List<WebElement> links = new WebDriverWait(driver, 5).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath("//h3/a")));

    WebElement link = links.get(idx);
    String href = link.getAttribute("href");

    link.click();

    System.out.println(idx + ": " + href + ": " + driver.getTitle());

    driver.navigate().back();
}

这会给你以下输出:

12 links
0: https://java.com/de/download/: Download der kostenlosen Java-Software
1: https://www.java.com/de/download/faq/java_win64bit.xml: Welche Java-Version soll für eine 64-Bit-Version des Windows-Betriebssystems heruntergeladen werden?
2: https://www.java.com/de/download/faq/remove_olderversions.xml: Warum sollte ich ältere Java-Versionen aus dem System deinstallieren?
3: https://www.java.com/de/download/help/download_options.xml: Wie installiere ich Java?
4: https://www.java.com/de/download/faq/whatis_java.xml: Was ist Java und warum brauche ich Java?
5: https://www.java.com/de/: java.com: Java + Sie
6: https://de.wikipedia.org/wiki/Java: Java – Wikipedia
7: https://de.wikipedia.org/wiki/Java-Technologie: Java-Technologie – Wikipedia
8: https://de.wikipedia.org/wiki/Java-Laufzeitumgebung: Java-Laufzeitumgebung – Wikipedia
9: https://www.oracle.com/de/java/: Java Software | Oracle Deutschland
10: http://stackoverflow.com/questions/tagged/java: Newest 'java' Questions - Stack Overflow
11: http://www.javacafe.at/: JAVA Premiumcafe - Ein Zeichen gehobener Gastlichkeit

请注意以下几点解决方案:

  1. 使用显式等待语句而不是隐式等待通常可以提供更可预测的结果,因为您可以更好地控制希望浏览器等待的
  2. 每次返回搜索结果页面时都必须重新找到元素并不理想,但这是避免陈旧元素问题的最简单方法。一个更优雅的解决方案是首先找到所有链接,存储他们的href并稍后单独导航到页面以检索页面标题。
  3. 因为我们必须在每次导航后再次找到元素,所以我们还必须应用明确等待所有链接再次可见。没有它,我们会得到相当随机的结果。