【问题标题】:How to scroll a specific DIV using Selenium WebDriver with Java?如何使用 Selenium WebDriver 和 Java 滚动特定的 DIV?
【发布时间】:2015-01-27 03:27:16
【问题描述】:

WebDriver无法识别某些WebElements,WebDriver无法找到浏览器可见区域中不可见的元素。

为了让 WebDriver 可以看到 WebElement,我们需要让该元素在浏览器的视图中可见,以便在特定的 div 上向下滚动!

如何在网页的特定区域执行我的操作(向下滚动并单击)。我尝试了很多,并没有帮助我。

请帮我解决我的问题。

【问题讨论】:

  • 请检查,我已经修改了我的答案。试试这个:JavascriptExecutor js = (JavascriptExecutor) 驱动程序; js.executeScript("javascript:window.scrollBy(250,350)");
  • @Pandiaraj - 这里显示的图像看起来像一个列表框。在那里你可以选择多个值。检查它是什么类型的 html 元素。 eg:-(检查它是否是一个 Select 元素)。如果是select元素,为什么不使用Select obj = new Select(element); obj.SelectByText("澳大利亚")。如果您想选择多个值,请使用 java 中的高级 for 循环来实现相同

标签: java selenium selenium-webdriver


【解决方案1】:

首先,这里发布的大多数答案都与主题无关。我现在一直在使用 selenium 2 和 selenium 3,webdriver 可以处理窗口滚动以使元素可见。

对于所有发布 sn-ps 的人来说:

driver.execute_script('scrollBy(0, 250)')

你根本不明白这个问题!

其实我还没有找到正确模拟滚动手柄拖动动作的方法,但this answer 看起来很有希望——但我没有尝试。

到目前为止,我个人有两种方法可以做到这一点:

  1. 使用Keys.ARROW_DOWN
  2. 使用Keys.PAGE_DOWN

其实还有第三种方式,直接放弃selenium,联系网站如果有提供API就可以了。

【讨论】:

  • 正确。同样对于element.send_keys(Keys.PAGE_DOWN),元素需要适合您的屏幕,否则 Selenium 将拒绝 send_keys() 命令。
  • 仅供参考,这个答案在 C# 中不起作用。驱动程序返回“无法聚焦元素”异常,因为您尝试在文本字段以外的其他内容上使用 SendKeys。单击元素以获得焦点没有任何效果。在这种情况下,看起来 javascript 可能仍然是最好的选择......
【解决方案2】:

最简单的方法是执行 Javascript 来向上/向下滚动元素。

JavascriptExecutor jsExec = (JavascriptExecutor) driver;
jsExec.executeScript("document.getElementById('id').scrollDown += 100");

【讨论】:

  • 您的意思是 scrollTop 而不是 scrollDown 吗? (目前正在使用 chrome)
【解决方案3】:
driver.get("http://www.***.com/");
driver.manage().window().maximize();
WebElement scroll = driver.findElement(By.id("someId"));
scroll.sendKeys(Keys.PAGE_DOWN);

【讨论】:

  • 我正在使用 Keys.DOWN 滚动,但是您如何识别滚动已加载来自 ajax 调用的新元素?我面临的问题是,在 Keys.DOWN 完成之前(没有加载新元素),我的脚本从 div 中获取旧的元素集。
  • 如果“someId”元素无法获得焦点,这将不起作用。
  • 好的,但是谁阻止您等待所有 dom 元素都下载完毕?或者点击打开隐藏元素的按钮或链接?
  • 谢谢。这个解决方案是今天唯一对我有用的解决方案。赞成。
【解决方案4】:

向下滚动:

import org.openqa.selenium.JavascriptExecutor;
WebDriver driver = new FirefoxDriver();
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("scroll(0, 250)"); //y value '250' can be altered

向上滚动:

JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("scroll(250, 0)"); //x value '250' can be altered

滚动页面底部:

JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("window.scrollTo(0,Math.max(document.documentElement.scrollHeight,document.body.scrollHeight,document.documentElement.clientHeight));");

Actions actions = new Actions(driver);
actions.keyDown(Keys.CONTROL).sendKeys(Keys.END).perform();

以慢动作完全滚动到底部:

for (int second = 0;; second++) {
    if(second >=60){
        break;
    }
    ((JavascriptExecutor) driver).executeScript("window.scrollBy(0,400)", ""); //y value '400' can be altered
    Thread.sleep(3000);
}

JavascriptExecutor jse = (JavascriptExecutor)driver;
for (int second = 0;; second++) {
    if(second >=60){
        break;
    }
    jse.executeScript("window.scrollBy(0,800)", ""); //y value '800' can be altered
    Thread.sleep(3000);
}

自动滚动到您的 WebElement:

Point hoverItem =driver.findElement(By.xpath("Value")).getLocation();
((JavascriptExecutor)driver).executeScript("return window.title;");    
Thread.sleep(6000);
((JavascriptExecutor)driver).executeScript("window.scrollBy(0,"+(hoverItem.getY())+");"); 
// Adjust your page view by making changes right over here (hoverItem.getY()-400)

((JavascriptExecutor)driver).executeScript("arguments[0].scrollIntoView();", driver.findElement(By.xpath("Value')]")));

WebElement element = driver.findElement(By.xpath("Value"));
Coordinates coordinate = ((Locatable)element).getCoordinates(); 
coordinate.onPage(); 
coordinate.inViewPort();

【讨论】:

  • 这只是每个与滚动相关的示例的复制粘贴工作,其中大多数与问题完全无关。问题是关于滚动特定的div 而不是滚动窗口本身。
  • @Rupesh Shinde:你确定你真的理解了这个问题吗?作者询问了如何在特定 div 中滚动内容,而您只是在这里复制了所有可能的如何滚动主窗口内容的方法,但这并没有真正的帮助。
  • 这个答案怎么能得到这么高的评价?,它与问题无关
  • 最后一个对我有用。我还在这里找到了解决方案sqa.stackexchange.com/a/17480/30196
  • 这是一个轻描淡写的答案,并没有回答所提出的问题,它不应该被赞成。
【解决方案5】:

使用JavascriptExceutorscrollIntoView()方法的另一种方法:

WebElement DIVelement = driver.findElement(By.xpath("xpath to div"));

JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("arguments[0].scrollIntoView(true)", DIVelement);

【讨论】:

    【解决方案6】:

    首先,您应该滚动而不是查找元素,如下所示:

    document.getElementById("your div id").scrollTop(250);
    

    在上面你可以找到那个特定的div。

    你也可以试试下面的:

    JavascriptExecutor js = (JavascriptExecutor) driver;
    js.executeScript("javascript:window.scrollBy(250,350)");
    

    【讨论】:

      【解决方案7】:

      假设您的 HTML 如下所示:

      <div id="someId" class="className" style="position: relative; top: 0px; left: opx;>
      

      您可以在div 中观察style 属性 检查top 的值,在上面的例子中是 0px

      现在尝试执行以下操作:

      $('.className').animate({top: "-60px"});
      

      这将帮助您向下滚动。 它是一个 JavaScript 执行器,所以你当然需要实现它。

      【讨论】:

        【解决方案8】:

        我的“解决方法”是通过元素的 x 和 y 坐标滚动到该位置。我还为 y 添加了一个偏移量,这样任何页眉/页脚或其他元素都不会阻挡我想要滚动到的元素的可见性。

        我在这个问题下发布了我的答案 -

        Selenium webdriver can't click on a link outside the page

        【讨论】:

          【解决方案9】:

          所有发布的答案都不适合我,但是我找到了基于 this post 的解决方案。

          ((JavascriptExecutor) driver).executeScript(
              "arguments[0].scrollTop=arguments[1].offsetTop",
              divWithScrollbarElement,
              elementToScrollTo);
          

          divWithScrollbarElement 是您要滚动的 div 元素,elementToScrollTo 是您想要使其可见的子元素(在我的情况下,它实际上是我最初尝试的元素的父元素看法)。如果 elementToScrollTo 实际上还没有在 DOM 中,您可能需要使用脚本一次尽可能向下滚动,然后再次加载更多元素。

          【讨论】:

            【解决方案10】:

            如您所见,webdriver 不会找到不可见的元素,因此您需要滚动到该元素。但是,您不能直接滚动到该元素,因为 webdriver 在它可见之前不会找到它。第 22 条军规。

            但是我确实有一种方法可以在 DIV 中滚动。首先将要滚动的 DIV 分配给一个元素变量,然后您可以使用 javascript 滚动该元素而不是滚动整个窗口。

            一些应该很容易适应其他语言的 VB.NET 示例代码:

            Dim div_to_scroll As IWebElement = driver.FindElement(By.XPath("[put your xpath here]"))
            
            driver.ExecuteJavaScript("arguments[0].scrollBy(0,500)", div_to_scroll)
            
            ' Short pause to make sure the screen updates:
            System.Threading.Thread.Sleep(500)
            

            如果您不知道需要滚动多远,那么您将需要一个带有测试的循环来查看所需元素是否可见。这不是一种特别优雅或快速的做事方式,但 webdriver 并不是一个快速的解决方案,我发现这种方法非常健壮。

            【讨论】:

              【解决方案11】:

              以防万一有人在寻找替代解决方案,我在这里使用 python,它应该很容易转换为 Java。首先,我使用的是:

              more = panel.find_elements(By.CSS_SELECTOR, "//li")
              self.driver.execute_script("arguments[0].scrollIntoView();", more[-1])
              
              if last == more[-1]:
                  break
              else:
                  last = more_followers[-1]
                  #wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, "//li")))
                  time.sleep(0.5)
              

              在 div 内的 ul 循环中。但是,出现的 li 元素越多,执行此动作的速度最慢的是硒。最后,因为包含 ul 的 div 有一个唯一的类名,所以我在循环中使用了以下内容:

              while num_of_il<num_of_elements:
                      self.driver.execute_script("document.getElementsByClassName('myclass')[0].scrollTop += 100;");
                      time.sleep(0.5)
                      num_of_il = self.driver.execute_script("return document.getElementsByTagName('li').length")
                      print("Num of li "+str(num_of_il))
              

              这种方式不再慢了,有了 0.5 我给了足够的时间来加载我的下一个条目。您还可以将其他 getElementsBy 用作 getElementById()、getElementsByName()、getElementsByTagName() 和 getElementsByTagNameNS()。查看https://developer.mozilla.org/en-US/docs/Web/API/document/ 的方法您可以通过访问 num_of_il 变量来检查加载的元素数量。考虑引入一些代码来打破循环,以防 num_of_il 没有改变(例如到达项目的末尾)。

              【讨论】:

                猜你喜欢
                • 2016-10-02
                • 2015-06-28
                • 2012-03-15
                • 2017-01-03
                • 2013-04-14
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多