【问题标题】:selenium webdriver does not find the correct number of elementsselenium webdriver 找不到正确数量的元素
【发布时间】:2019-11-03 11:03:57
【问题描述】:

最初,我在这里发布了我的问题:

Extracting content from a dynamic web site using a Java Library

然后,在阅读并应用以下问题的信息后:

Selenium Webdriver : not displaying the correct Li elements

我安装了 selenium chrome 驱动程序(版本 ChromeDriver 74.0.3729.6),我的 chrome 浏览器版本为 74.0.3729.169。 selenium WebDriver java 对象仍然无法正确找到我网页上的元素数量,尽管我模拟了向下滚动并且驱动程序打开的 chrome 浏览器确实正确显示了 20 个元素的总数。

    import java.util.List;

    import org.openqa.selenium.By;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.chrome.ChromeDriver;
    import org.openqa.selenium.support.ui.ExpectedConditions;
    import org.openqa.selenium.support.ui.WebDriverWait;

     public class ImmoweltBot {

    public static final String URL2 = "https://www.immowelt.at/liste/wien-2-leopoldstadt/wohnungen/mieten?sort=price&cp=2";


    public static void main(String[] args) throws Exception {
        System.setProperty("webdriver.chrome.driver", "C:\\Temp\\chromedriver.exe");

        WebDriver webDriver = new ChromeDriver();
        webDriver.get(URL2);
        WebDriverWait wait = new WebDriverWait(webDriver, 15);
        By searchResults = By.xpath("//*[contains(@class, 'listitem clear relative js-listitem')]");

        JavascriptExecutor js = (JavascriptExecutor)webDriver;
        webDriver.manage().window().maximize();
        js.executeScript("window.scrollBy(0,1000)");

        wait.until(ExpectedConditions.numberOfElementsToBeMoreThan(searchResults, 4));
        List<WebElement> elemnts = webDriver.findElements(searchResults);
        System.out.println(elemnts.size());
    }

}

我的网页:

https://www.immowelt.at/liste/wien-2-leopoldstadt/wohnungen/mieten?sort=price&cp=2

任何帮助将不胜感激。谢谢!

【问题讨论】:

    标签: java selenium selenium-webdriver web-scraping selenium-chromedriver


    【解决方案1】:

    这有点棘手。您必须使用无限循环来检查元素 size() 并向下滚动到页面一旦达到 20 它将跳出循环。

    WebDriver driver = new ChromeDriver();
    driver.get("https://www.immowelt.at/liste/wien-2-leopoldstadt/wohnungen/mieten?sort=price&cp=2");
    WebDriverWait wait = new WebDriverWait(driver, 15);
    
    while(true){
    
      List<WebElement> elemnts=wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.xpath("//div[contains(@class, 'listitem clear relative js-listitem')]")));                               
    
       driver.findElement(By.tagName("body")).sendKeys(Keys.DOWN);
    
       if (elemnts.size()==20)
           {
              System.out.println(elemnts.size());   
              break;
           }               
    
            } 
    

    【讨论】:

    • 谢谢!我应该在最后一页做什么,元素的最大数量是 20,但实际的元素可能会更少?
    • 检查计数并给出条件if(elemnts.size()&gt;=count)
    • 如果大小永远不会达到 20,请确保添加超时或最大重试次数。
    【解决方案2】:

    感谢您提出这个问题,这很有挑战性。所以这是我的解决方案。 这是平滑滚动直到向下的 js。

    (async function() {
    function sleep() {
        return new Promise(resolve => setTimeout(resolve, 500))
    };
    var height;
    do {
        height = document.body.scrollHeight;
        window.scrollTo({
            "behavior": "smooth",
            "left": 0,
            "top": document.body.scrollHeight
        });
        await sleep()
    } while (height != document.body.scrollHeight)})();
    

    我使用异步函数是因为 chomedriver.executeScript() 希望异步函数使用 'await' 语句。

    String scrollWhileScrollsJS = "(async function(){function sleep(){return new Promise(resolve=>setTimeout(resolve,500))};var height;do{height=document.body.scrollHeight;window.scrollTo({\"behavior\":\"smooth\",\"left\":0,\"top\":document.body.scrollHeight});await sleep()}while(height!=document.body.scrollHeight)})();";
    ( (ChromeDriver) webDriver ).executeScript( scrollWhileScrollsJS );
    

    当然我们需要流畅的等待。为此,我发现只有当我们位于页面底部时,'scrollY'才会等于'document.body.scrollHeight-innerHeight'。

    new FluentWait<>( webDriver ).withTimeout( Duration.ofSeconds( 10 ) )
                                 .pollingEvery( Duration.ofMillis( 500 ) )
                                 .until( result -> ( (ChromeDriver) webDriver ).executeScript( "return scrollY" ).equals( ( (ChromeDriver) webDriver ).executeScript( "return document.body.scrollHeight-innerHeight" ) ) );
    

    因此,您可以使用此代码滚动页面,等待它滚动到最后并在不知道应该有多少的情况下获取元素。

    PS:请不要...我的意思是,真的,不要在自动化测试中使用 while(true)。

    【讨论】:

    • 在自动化测试中使用while(true) 时有任何已知问题吗?
    • 当出现问题时(你 101% 确定它不会出现问题)并且你在发布前一天有一个挂起的测试运行。
    • 还是不清楚,能补充几行更新答案吗?
    • 还是不清楚你想从我这里读到什么?带有条件中断的 while-true 可能无法达到条件?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-11
    • 1970-01-01
    • 2016-09-07
    • 2017-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多