如何在不使用 for 循环的情况下转储 <WebElement>list 的内容

How to dump the content of <WebElement>list without using for loop

我正在尝试使用 for 循环将列表的内容写入文件。是否可以用一条语句转储列表的全部内容?目前它很慢。我想加快程序速度。

By getChanges = By.xpath("//td[contains(@class,'blob-code blob-code-addition') or contains(@class,'blob-code blob-code-deletion')]");

List<WebElement> listChanges = driver.findElements(getChanges);

for (int count = 0; count < listChanges.size(); count++) {

    String codeChanges=driver.findElements(getChanges).get(count).getText();

    outputHandle.write(codeChanges);
}

要添加更多详细信息,当我在此页面上时 https://github.com/SunriseSoftVN/qlkh/commit/a8b1c3a241ccf83f33819f4b04a8d647238bdaf8#diff-33c32c1890dcfb06827b5db4bee85959

ListChanges 大小为 :3408,它永远卡在那里。我的意思是它需要很多时间。它不会进入无限循环,因为文件正在按预期正确写入。

添加更多代码以显示正在使用的两个级联 for 循环。外循环在第二次迭代中失败,错误是页面上的内容已更改,即使它没有更改。只有当我用 listChanges 替换对 findElements 的调用时才会发生这种情况。

By getCommitList = By.xpath("//a[contains(@class,'sha button-outline')]");

                List<WebElement> commitList = driver.findElements(getCommitList);

//              System.out.println("ListChanges size is :" + commitList.size());

                for(int commitCount = 0; commitCount < commitList.size(); commitCount++)
                {
                    String commitName=driver.findElements(getCommitList).get(commitCount).getText(); //works but redundant call

//                  String commitName=commitList.get(commitCount).getText();

                    System.out.println(commitName);

//                  commitList.get(commitCount).click();  //suggested improvement but fails

                    driver.findElements(getCommitList).get(commitCount).click();

                    By getChanges = By.xpath("//td[contains(@class,'blob-code blob-code-addition') or contains(@class,'blob-code blob-code-deletion')]");

                    List<WebElement> listChanges = driver.findElements(getChanges);

                System.out.println("ListChanges size is :" + listChanges.size());

                    for (int count = 0; count < listChanges.size(); count++) {

//                      System.out.println(driver.findElements(getChanges).get(count).getText());  //prints all the code changes associated with each commit

//                      String codeChanges=driver.findElements(getChanges).get(count).getText();

                        String codeChanges=listChanges.get(count).getText();

//                      System.out.println("Writing code changes into file now *********");

                        outputHandle.write(codeChanges);

                        outputHandle.write("\n");

                    }
                    //AFTER FINISHING FIRST COMMIT, YOU MOVE TO THE NEXT COMMIT ON PREVIOUS PAGE

                    driver.navigate().back();

添加以下错误信息:

Exception in thread "main" org.openqa.selenium.StaleElementReferenceException: Element not found in the cache - perhaps the page has changed since it was looked up
Command duration or timeout: 14 milliseconds
For documentation on this error, please visit: http://seleniumhq.org/exceptions/stale_element_reference.html

目前,您的代码是这样做的:

  • 找到所有元素
  • 再次找到所有元素
  • 写入第一个元素
  • 再次找到所有元素
  • 写第二个元素
  • 再次找到所有元素
  • 写第三个元素
  • ...等等

String codeChanges=driver.findElements(getChanges).get(count).getText();
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

看到对 driver.findElements 的调用了吗?找到所有元素......每次循环。

您可能想将其替换为 listChanges 以使用您之前进行的搜索的结果。

我同意@immibis。作为证明,我在 Chrome

上对代码进行了以下更改测试
By getChanges = By.xpath("//td[contains(@class,'blob-code blob-code-addition') or contains(@class,'blob-code blob-code-deletion')]");

List<WebElement> listChanges = driver.findElements(getChanges);

for (int count = 0; count < listChanges.size(); count++) {

  String codeChanges = listChanges.get(count).getText();

  System.out.println(codeChanges);
}

在每次迭代中,您都导航到一个提交列表。进入该提交列表页面后,您将遍历该列表中的所有提交详细信息。

您无法将提交列表组缓存到变量,因为您在每次迭代时都会离开该页面。但是,您不需要每次都查找整个 link 组。您只需要查找您要点击的列表 link。

String listSearchXPath = "//a[contains(@class,'sha button-outline')]";

// Count how many commit lists we need to lookup
int commitListSize = driver.findElements(By.xpath(listSearchXPath)).size()
System.out.println("ListChanges size is :" + commitListSize);

for(int commitCount = 0; commitCount < commitListSize; commitCount++)
    {
        // Lookup the link we're going to click on by adding an  
        // XPath index filter for the current iteration
        WebElement linkToClick = driver.findElement(By.xpath(listSearchXPath + "[" + commitCount.ToString + "]"));

        System.out.println(linkToClick.getText());

        // Click on the link. We're navigating to a new page
        // so we cannot reference this element again.
        linkToClick.click();

        // Do a new search for the details in the commit list
        List<WebElement> listChanges = driver.findElements(By.xpath("//td[contains(@class,'blob-code blob-code-addition') or contains(@class,'blob-code blob-code-deletion')]"));

        System.out.println("ListChanges size is :" + listChanges.size());

        // Iterate through the details and log to a file
        for (int count = 0; count < listChanges.size(); count++) {

            // We're still on the same page so we can reference our saved element
            // instead of doing a new search.
            String codeChanges = listChanges.get(count).getText();

            outputHandle.write(codeChanges + "\n");
    }

    //AFTER FINISHING FIRST COMMIT, YOU MOVE TO THE NEXT COMMIT ON PREVIOUS PAGE
    driver.navigate().back();
}