简体   繁体   English

如何使用带有 Java 的 Selenium WebDriver 滚动特定的 DIV?

[英]How to scroll a specific DIV using Selenium WebDriver with Java?

Some of WebElements are not recognized by WebDriver, WebDriver fails to find the element which is not visible in browser's visible area. WebDriver 无法识别某些 WebElements,WebDriver 无法找到浏览器可见区域中不可见的元素。

In order to make the WebElement viewable by WebDriver, We need to make that element to visible in browser's view to do scroll down on particular div!为了使 WebElement 可被 WebDriver 查看,我们需要使该元素在浏览器视图中可见,以便在特定 div 上向下滚动!

How can I perform my action(scroll down and click) on particular area of my webpage.如何在网页的特定区域执行操作(向下滚动并单击)。 I tried lot, doesn't helped me.我尝试了很多,对我没有帮助。

Please help me resolve my issue.请帮我解决我的问题。

First of all, most of the answers posted here are just off the topic.首先,这里发布的大多数答案都与主题无关。 I have been working with selenium 2 and selenium 3 now, the webdriver can handle window scroll to make an element visible.我现在一直在使用 selenium 2 和 selenium 3,webdriver 可以处理窗口滚动以使元素可见。

For everyone posting snippets like:对于每个发布片段的人,如:

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

you do not get the question at all!你根本不明白这个问题!

Actually I still did not find a way to properly simulate the drag action of scroll handle but this answer seems promising -- but I did not try.实际上我仍然没有找到一种方法来正确模拟滚动手柄的拖动动作,但这个答案似乎很有希望——但我没有尝试。

So so far personally there are two ways to do this for me:到目前为止,我个人有两种方法可以做到这一点:

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

Actually there is a third way, just give up selenium and contact the website if they provide any API.其实还有第三种方式,就是放弃selenium,联系网站,如果他们提供任何API。

The easiest way to do that is executing a Javascript to scroll the element up/down.最简单的方法是执行 Javascript 来向上/向下滚动元素。

JavascriptExecutor jsExec = (JavascriptExecutor) driver;
jsExec.executeScript("document.getElementById('id').scrollDown += 100");
driver.get("http://www.***.com/");
driver.manage().window().maximize();
WebElement scroll = driver.findElement(By.id("someId"));
scroll.sendKeys(Keys.PAGE_DOWN);

Scroll Down:向下滚动:

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

Scroll up:向上滚动:

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

Scroll bottom of the Page:滚动页面底部:

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

or或者

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

Full scroll to bottom in slow motion:以慢动作完全滚动到底部:

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);
}

or或者

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);
}

Scroll automatically to your WebElement:自动滚动到您的 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)

or或者

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

or或者

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

Another way of doing it using JavascriptExceutor 's scrollIntoView() method:使用JavascriptExceutorscrollIntoView()方法的另一种方法:

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

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

First you should do scroll rather than find element so do like below :首先,您应该滚动而不是查找元素,如下所示:

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

After above you can find that specific div.在上面之后你可以找到那个特定的 div。

You can also try below :您也可以尝试以下:

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

Consider your HTML is like below:考虑您的 HTML 如下所示:

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

you can observe style attribute in div check for the value of top which is 0px in above example您可以观察div style属性检查top的值,在上面的示例中为0px

Now try to do something like:现在尝试执行以下操作:

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

which will help you to scroll down.这将帮助您向下滚动。 Its a JavaScript executor so of course you need to implement it.它是一个 JavaScript 执行器,所以你当然需要实现它。

My 'WORKAROUND' is to scroll to the position by element's x and y co-ordinates.我的“解决方法”是按元素的 x 和 y 坐标滚动到位置。 I also added an offset to y so that any header/footer or other element don't block the visibility of the element that I want to scroll to.我还为 y 添加了一个偏移量,以便任何页眉/页脚或其他元素都不会阻止我想要滚动到的元素的可见性。

I have my answer posted under this question -我在这个问题下发布了我的答案 -

Selenium webdriver can't click on a link outside the page Selenium webdriver 无法点击页面外的链接

None of the posted answers worked for me, however I have found a solution based on this post .没有一个已发布的答案对我有用,但是我找到了基于这篇文章的解决方案。

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

where divWithScrollbarElement is the div element which you are looking to scroll, and elementToScrollTo is the child element which you want to make viewable (which in my case was actually the parent of the element which I was initially trying to view).其中divWithScrollbarElement是您要滚动的 div 元素, elementToScrollTo是您希望使其可见的子元素(在我的情况下,它实际上是我最初尝试查看的元素的父元素)。 If elementToScrollTo is not actually in the DOM yet, you may need to use the script once to scroll down as far as possible, and then again once more elements have loaded.如果elementToScrollTo实际上还没有在 DOM 中,您可能需要使用脚本一次尽可能向下滚动,然后再次加载更多元素。

As you found, webdriver won't find elements that aren't visible so you need to scroll to the element.正如您所发现的,webdriver 不会找到不可见的元素,因此您需要滚动到该元素。 However you can't scroll directly to the element because webdriver won't find it until it is visible.但是,您不能直接滚动到该元素,因为 webdriver 在它可见之前不会找到它。 Catch-22.抓住-22。

However I do have a way that you can scroll within a DIV.但是,我确实有一种方法可以让您在 DIV 中滚动。 First assign the DIV you want to scroll to an element variable, and then you can use javascript to scroll that element instead of scrolling the entire window.首先将要滚动的 DIV 分配给元素变量,然后您可以使用 javascript 滚动该元素而不是滚动整个窗口。

Some VB.NET example code that should be easily adapted to other languages:一些应该很容易适应其他语言的 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)

If you don't know how far you need to scroll then you will need a loop with a test to see if the desired element is visible yet.如果您不知道需要滚动多远,那么您将需要一个带有测试的循环,以查看所需元素是否可见。 This isn't a particularly elegant or fast way of doing things but webdriver isn't a fast solution to begin with and I have found this method to be very robust.这不是一种特别优雅或快速的做事方式,但 webdriver 并不是一个快速的解决方案,我发现这种方法非常健壮。

Just in case for anyone looking for an alternative solution, here I put mine using python, which should be easy to transform to Java.以防万一有人在寻找替代解决方案,我在这里使用 python,它应该很容易转换为 Java。 First, I was using:首先,我使用的是:

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)

in a loop for a ul inside a div.在 div 内的 ul 循环中。 However, the more li elements appear, the slowest was selenium to perfom this action.然而,li 元素出现的越多,执行这个动作的最慢的是硒。 At the end, because the div containing the ul had a unique class name I used the following in a loop:最后,因为包含 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))

This way is not slow anymore, and with the 0.5 I give enough time to load my next entries.这种方式不再慢了,使用 0.5 我给了足够的时间来加载我的下一个条目。 You can also have other getElementsBy as getElementById(), getElementsByName(), getElementsByTagName() and getElementsByTagNameNS().您还可以使用其他 getElementsBy 作为 getElementById()、getElementsByName()、getElementsByTagName() 和 getElementsByTagNameNS()。 Look methods at https://developer.mozilla.org/en-US/docs/Web/API/document/ You can check the number of elements loaded accessing the num_of_il variable.https://developer.mozilla.org/en-US/docs/Web/API/document/查看方法您可以检查访问 num_of_il 变量时加载的元素数量。 Consider introducing some code to break the loop in case num_of_il does not change (eg end of items reached).考虑引入一些代码来打破循环,以防 num_of_il 没有改变(例如到达项目的末尾)。

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

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