简体   繁体   English

Selenium:在动态加载网页时滚动到页面末尾

[英]Selenium: Scroll to end of page in dynamically loading webpage

I have a webpage that keeps loading new items when scrolling down the page until every item is loaded.我有一个网页在向下滚动页面时不断加载新项目,直到加载每个项目。

I'm working with Selenium in Java, and need to scroll down to the bottom of the page in order to load everything.我在 Java 中使用 Selenium,需要向下滚动到页面底部才能加载所有内容。

I have tried several different options, like scrolling to an element of the bottom of the page:我尝试了几种不同的选择,比如滚动到页面底部的一个元素:

WebElement copyrightAtEndOfPage = webDriver.findElement(By.xpath("//a[@href='/utils/copyright.html']"));
((JavascriptExecutor) webDriver).executeScript("arguments[0].scrollIntoView();", copyrightAtEndOfPage);

This only scrolls down once though, and then the webpage keeps loading.这只会向下滚动一次,然后网页会继续加载。

I also tried this approach, which also only scrolls down once, because it only takes the browser height into consideration.我也尝试过这种方法,它也只向下滚动一次,因为它只考虑了浏览器的高度。

Any help is highly appreciated.非常感谢任何帮助。

I will provide you code in Python for this.为此,我将为您提供 Python 代码。 I think it's easy to translate to Java:我认为翻译成Java很容易:

def scroll_down(self):
    """A method for scrolling the page."""

    # Get scroll height.
    last_height = self.driver.execute_script("return document.body.scrollHeight")

    while True:

        # Scroll down to the bottom.
        self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

        # Wait to load the page.
        time.sleep(2)

        # Calculate new scroll height and compare with last scroll height.
        new_height = self.driver.execute_script("return document.body.scrollHeight")

        if new_height == last_height:

            break

        last_height = new_height

Hope it helps you!希望对你有帮助!

Thanks to Ratmir Asanov (see the approved answer above), I translated the Python code into Java to make it easier to implement for other people.感谢 Ratmir Asanov(参见上面批准的答案),我将 Python 代码翻译成 Java,以便其他人更容易实现。

try {
    long lastHeight = (long) ((JavascriptExecutor) webDriver).executeScript("return document.body.scrollHeight");

    while (true) {
        ((JavascriptExecutor) webDriver).executeScript("window.scrollTo(0, document.body.scrollHeight);");
        Thread.sleep(2000);

        long newHeight = (long) ((JavascriptExecutor) webDriver).executeScript("return document.body.scrollHeight");
        if (newHeight == lastHeight) {
            break;
        }
        lastHeight = newHeight;
    }
} catch (InterruptedException e) {
    e.printStackTrace();
}

Updated Johannes code a bit to make it functional.稍微更新了 Johannes 代码以使其正常运行。

JavascriptExecutor js = (JavascriptExecutor) driver;
try {
    long lastHeight=((Number)js.executeScript("return document.body.scrollHeight")).longValue();
    while (true) {
        ((JavascriptExecutor) driver).executeScript("window.scrollTo(0, document.body.scrollHeight);");
        Thread.sleep(2000);

        long newHeight = ((Number)js.executeScript("return document.body.scrollHeight")).longValue();
        if (newHeight == lastHeight) {
            break;
        }
        lastHeight = newHeight;
    }
} catch (InterruptedException e) {
    e.printStackTrace();
}

C# version of the Ratmir Asanov's answer: Ratmir Asanov 答案的 C# 版本:

var lastHeight =  driver.ExecuteScript("returndocument.body.scrollHeight");
while (true)
{
    driver.ExecuteScript("window.scrollTo(0, document.body.scrollHeight);");
    await Task.Delay(500);

    var newHeight = driver.ExecuteScript("return document.body.scrollHeight");
    Console.WriteLine(lastHeight + " - " + newHeight);
    if (newHeight.Equals(lastHeight))
        break;

    lastHeight = newHeight;
}

Updating the above solution by Prabhat further as it was still giving me compilation error. Prabhat 进一步更新上述解决方案,因为它仍然给我编译错误。

    try {
        Object lastHeight = ((JavascriptExecutor) driver).executeScript("return document.body.scrollHeight");

        while (true) {
            ((JavascriptExecutor) driver).executeScript("window.scrollTo(0, document.body.scrollHeight);");
            Thread.sleep(2000);

            Object newHeight = ((JavascriptExecutor) driver).executeScript("return document.body.scrollHeight");
            if (newHeight.equals(lastHeight)) {
                break;
            }
            lastHeight = newHeight;
        }
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

I found another solution to the dynamically loading page.我找到了另一个动态加载页面的解决方案。

Count the elements that are displayed every scroll before and after the scroll and compare them to determine if you've scrolled to the bottom.计算滚动前后每次滚动显示的元素,并比较它们以确定您是否已滚动到底部。

var reachedEnd = false;
oldCount = driver.FindElements(By.CssSelector(".searchDataContainer.table-row.raw")).Count;

while (!reachedEnd)
{
    driver.FindElement(By.CssSelector("body")).SendKeys(Keys.End);
    Thread.Sleep(500);
    oldCount = driver.FindElements(By.CssSelector(".searchDataContainer.table-row.raw")).Count;

    if (newCount == oldCount)
    {
        reachedEnd = true;
    }
    else
    {
        newCount = oldCount;
    }
}

Updated code that worked for me:更新了对我有用的代码:

try {
                    long lastHeight = (long) ((JavascriptExecutor) driver).executeScript("return document.body.scrollHeight");
                    int cont=1000;
                    while (true) {
                        ((JavascriptExecutor) driver).executeScript("window.scrollTo(0, "+cont+");");
                        Thread.sleep(2000);

                        long newHeight = (long) ((JavascriptExecutor) driver).executeScript("return document.body.scrollHeight");
                        if (newHeight <= cont) {
                            break;
                        }
//                      lastHeight = newHeight;
                        cont+=500;
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

Making a slight correction to the above stated answers.对上述答案稍作修正。 The variable 'start' of type long keeps changing after every scroll and the value becomes same after it reaches the end of the webpage. long 类型的变量 'start' 在每次滚动后都会不断变化,并且在到达网页末尾后值变得相同。 And as it an infinite loop with will keep returning the same value again and again.因为它是一个无限循环,它会一次又一次地返回相同的值。 So, I just took the 'temp' variable and checked two consecutive values are same or not as the values remain same after the end is reached.所以,我只是取了'temp'变量并检查了两个连续的值是否相同,因为在到达终点后值保持不变。 As soon at it finds the same it exits the loop.一旦找到相同的内容,它就会退出循环。

    try {
            long temp = 0;
            while (true) {
                ((JavascriptExecutor) driver).executeScript("window.scrollTo(0, document.body.scrollHeight);");
                Thread.sleep(2500);
                long start = (Long) ((JavascriptExecutor) driver).executeScript("return document.body.scrollHeight");
                if (start == temp) {
                    break;
                }
                temp = start;
            }
            System.out.println("completed the scroll");
        } catch (Exception e) {
            e.printStackTrace();
        }

您可以添加以下代码以保持按下页面向下按钮:

new Actions(driver).sendKeys(Keys.PAGE_DOWN).perform();

to scroll and wait to load more property till end滚动并等待加载更多属性直到结束

                lenOfPage = driver.instance.execute_script("window.scrollTo(0, document.body.scrollHeight);var lenOfPage=document.body.scrollHeight;return lenOfPage;")

                match = False
                while not match:
                    lastCount = lenOfPage
                    time.sleep(2)
                    lenOfPage = driver.instance.execute_script("window.scrollTo(0, document.body.scrollHeight);var lenOfPage=document.body.scrollHeight;return lenOfPage;")

                    if lastCount == lenOfPage:
                        match = True

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM