使用webdriver滚动到元素?


72

我仍在学习,并在回答我的一个问题:在这里,我被告知可能是由于没有考虑到所涉及的元素。

我仔细阅读了文档和SO,这是最相关的答案:这里

您可以使用“ org.openqa.selenium.interactions.Actions”类移动到元素:

WebElement element = driver.findElement(By.id("my-id"));
Actions actions = new Actions(driver);
actions.moveToElement(element);
## actions.click();
actions.perform();

当我尝试使用以上内容滚动到元素时:它表示未定义WebElement。

我认为这是因为我尚未导入相关模块。有人可以指出我应该导入的内容吗?

编辑:正如alecxe指出的,这是Java代码。

但是与此同时,在试图弄清楚一段时间之后。我发现了WebElement的导入方法:

from selenium.webdriver.remote.webelement import WebElement

可能会帮助像我这样的人。

IMO也是一个很好的教训:

去:文档

class selenium.webdriver.remote.webelement.WebElement(parent, id_, w3c=False)

需要分成上面提到的命令形式。

Answers:


130

您正在尝试使用Python运行Java代码。在Python / Selenium中,org.openqa.selenium.interactions.Actions反映在ActionChains类中

from selenium.webdriver.common.action_chains import ActionChains

element = driver.find_element_by_id("my-id")

actions = ActionChains(driver)
actions.move_to_element(element).perform()

或者,您也可以通过以下方式“滚动查看” scrollIntoView()

driver.execute_script("arguments[0].scrollIntoView();", element)

如果您对这些差异感兴趣:


啊...我花了3个小时尝试在SO和文档中找到的每种方法。我尝试了第一个解决方案,但一定以某种方式弄乱了它。我将阅读ScrollIntoView与moveToElement。只是一个简单的问题,我需要执行相同的步骤100次,我正在考虑使用for循环。这是一个好方法吗?
Sid

@Sid很难说。在某些情况下,您可以将操作链接成一个循环,然后在循环后执行一次,但这完全取决于用例。看看是否有必要为此创建一个单独的SO主题。谢谢。
alecxe

move_to_element(ele).perform()滚动到某个元素,即使该元素当前不在视图中?
老男孩

1
@alecxe我不知道它是如何工作的(它不适用于我的项目),因为如果对象不可见,硒如何找到要滚动到的对象?我的无法找到我要滚动到的元素。
吉普车mcface

2
当我按照您的建议调用move_to时,出现了selenium.common.exceptions.MoveTargetOutOfBoundsException:消息:(164,1297)超出了视口的宽度(1366)和高度(694)。我很感谢您的回答,我认为这是解决问题的方法(而且我已经从您的回答中了解了ActionChains),但是看起来它需要一些改进。Thanks1
dotz

53

它不是问题的直接答案(不是Actions),但还可以让您轻松滚动至所需元素:

element = driver.find_element_by_id('some_id')
element.location_once_scrolled_into_view

这实际上是要返回您页面上元素的坐标(xy),但也向下滚动到目标元素


谢谢@Andersson,我试图找到解决方法,因为您指出这可能是另一个问题的问题。:)
Sid

2
首先,我附加了()后面,并且错误“ dict'对象不可调用”,我检查了元素类型为WebElement。然后我删除 () 并工作。这不是一种方法吗?我的意思是,为什么()不需要?
雷杨

1
@LeiYang,因为location_once_scrolled_into_view是Python属性。属性不带参数(对象实例-self除外),并且应在不带括号的情况下调用
Andersson

1
@Andersson .move_to_element()对我不起作用(我对alecxe答案进行了评论),但您的解决方案起作用了。谢谢!
dotz,

@LeiYang这是关于的源代码location_once_scrolled_into_view,以帮助解释为什么()不需要:selenium / webelement.py,网址为d3b6ad006bd7dbee59f8539d81cee4f06bd81d64·SeleniumHQ / selenium
DataAlchemist,

3

除了move_to_element()scrollIntoView()我还想提出以下代码,尝试将元素在视图中居中

desired_y = (element.size['height'] / 2) + element.location['y']
window_h = driver.execute_script('return window.innerHeight')
window_y = driver.execute_script('return window.pageYOffset')
current_y = (window_h / 2) + window_y
scroll_y_by = desired_y - current_y

driver.execute_script("window.scrollBy(0, arguments[0]);", scroll_y_by)

感谢您的解决方案,尝试了其他方法,但元素不可点击。有时滚动不足,元素位于底部的“聊天框”下方,其他代码过多的滚动元素位于下方顶部。菜单
万卡

0

如果元素具有属性,还有另一个选项可将页面滚动到所需元素"id"

如果您想使用浏览到页面并向下滚动到元素@id,则可以通过添加#element_id到URL来自动完成...

假设我们需要导航到Selenium Waits文档,并将页面向下滚动到“隐式等待”部分。我们能做的

driver.get('https://selenium-python.readthedocs.io/waits.html')

并添加滚动代码...或使用

driver.get('https://selenium-python.readthedocs.io/waits.html#implicit-waits')

导航到页面并使用id="implicit-waits"<div class="section" id="implicit-waits">...</div>)自动将页面滚动到元素


0

您可以使用javascript通过该execute_javascript方法滚动到该元素。例如,这是我在Robot Framework上使用SeleniumLibrary的方法:

web_element = self.selib.find_element(locator)
self.selib.execute_javascript(
    "ARGUMENTS",
    web_element,
    "JAVASCRIPT",
    'arguments[0].scrollIntoView({behavior: "instant", block: "start", inline: "start"});'
)

0

这可以使用driver.execute_script()来完成:

driver.execute_script("document.getElementById('myelementid').scrollIntoView();")

0

例:

driver.execute_script("arguments[0].scrollIntoView();", driver.find_element_by_css_selector(.your_css_selector))

对于任何类型的选择器,这始终对我有用。也有Actions类,但是对于这种情况,它不是那么可靠。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.