【问题标题】:Selenium - Wait for the ScrollIntoView to finishSelenium - 等待 ScrollIntoView 完成
【发布时间】:2021-01-22 11:26:16
【问题描述】:

我需要滚动到一个元素并截取页面的屏幕截图,但驱动程序在页面完全滚动到该元素之前截取了屏幕截图。我用这种方式睡了一段时间

driver.execute_script("""arguments[0].scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'start' });""", element)
time.sleep(1)
scr = driver.get_screenshot_as_png()

但我真的不想使用 sleep,因为它们不是面向测试的。我试图等待元素可见,但它也不起作用。另一种尝试是使用 ActionChains 移动到元素,但它没有显示整个元素在其上移动。有没有办法等待滚动完成?除了屏幕截图的这种特殊情况之外,了解等待滚动完成的方法会很有用。

【问题讨论】:

    标签: javascript python selenium


    【解决方案1】:
    public static void fullScren(String filename) throws IOException
    {
    
            Screenshot myScreenshot = new AShot().shootingStrategy(ShootingStrategies.viewportPasting(100)).takeScreenshot(driver);
            ImageIO.write(myScreenshot.getImage(),"PNG",new File("src/main/java/ScreenShots/" + filename + ".jpg"));
        }
    

    你必须使用这个向下滚动并通过 selenium 拍摄全屏

    【讨论】:

    • Ashot 用于此
    【解决方案2】:
    WebDriverWait(driver,30).until(EC.visibility_of_element_located((By.XPATH,"yourelementslocator")))
    

    使用预期条件的可见性

    【讨论】:

    • 这不起作用,因为即使元素不完全可见也满足可见性
    • 执行脚本是同步的,只有在动作完成后才返回
    • 添加 time.sleep 后你得到了正确的屏幕截图吗?
    • 如果您删除属性并仅使用 scrollintoview() 会发生什么
    • 在 time.sleep 之后,我得到了正确的屏幕截图,如果我删除了属性,它会滚动到元素,但它并没有完全显示元素,因为它是一个很大的元素
    【解决方案3】:

    我找到了一个使用 Javascript 等待元素完全可见的解决方案:

    def wait_until_specific_condition(func, timeout=30):
      
        endtime = time.time() + timeout
        while True:
           if time.time() > endtime:
                raise TimeoutException("The condition is not satisfied")
           result = func()
           if result is True:
                return result
    

    因此,使用此功能,我会等到满足特定条件;在我的情况下,条件是使用 Javascript 以这种方式获得的元素的整个可见性:

    driver.execute_script("arguments[0].scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'start' });",
                              element)
    is_visible_script = """function isScrolledIntoView(el) {
                                        var rect = el.getBoundingClientRect();
                                        var elemTop = rect.top;
                                        var elemBottom = rect.bottom;
                                    
                                        // Only completely visible elements return true:
                                        var isVisible = (elemTop >= 0) && (elemBottom <= window.innerHeight);
                                        // Partially visible elements return true:
                                        //isVisible = elemTop < window.innerHeight && elemBottom >= 0;
                                        return isVisible;
                                    }
                               return isScrolledIntoView(arguments[0]);"""
    wait_until_specific_condition(lambda: driver.execute_script(is_visible_script, element))
    

    【讨论】:

    • 这还能用吗?
    • 是的,它仍然对我有用
    猜你喜欢
    • 2023-01-28
    • 2014-05-27
    • 1970-01-01
    • 2018-08-20
    • 2018-11-28
    • 2014-01-03
    • 2015-03-14
    • 1970-01-01
    • 2018-05-25
    相关资源
    最近更新 更多