【问题标题】:Scroll up and down to get Element into View with Selenium Python上下滚动以使用 Selenium Python 将元素放入视图
【发布时间】:2018-07-21 17:41:24
【问题描述】:

我需要能够向上滚动,然后向下滚动才能找到带有 Selenium 的元素。
我已经看到了很多问题和答案,我发现的主要思想是self.web_driver.execute_script("return arguments[0].scrollIntoView(true);", element),这就是我目前在我的代码中的内容。但这还不够好,因为此代码仅向下滚动,因此如果元素位于可滚动视图的上部,则无法找到该元素。
所以我需要一个首先向上滚动(向上翻页?)然后开始向下滚动的脚本。
我试过这样的事情

self.web_driver.execute_script("return arguments[0].scrollIntoView(true);", element) 
self.web_driver.execute_script("window.scrollTo(0, -document.body.scrollHeight);")
self.web_driver.execute_script("return arguments[0].scrollIntoView(true);", element)

但这不会向上滚动:(

【问题讨论】:

  • 一个元素是(只有一个)元素,你为什么要一次又一次地上下滚动才能看到元素?除非 DOM 发生变化,否则任何元素的位置都必须是固定的。
  • 因为这个函数(find_the_element)应该是通用的,有时元素在视图的上侧,有时在视图的下侧,我不知道它在哪里。我需要将 XPATH 传递给函数,它会找到(点击)元素
  • 确切地说,无论元素是向上还是向下,都会被显示出来。您只需传递 xpath。无需特别向上或向下滚动。
  • 但是不行! self.web_driver.execute_script("return arguments[0].scrollIntoView(true);", element) 只向下滚动!不管脚本里面是真还是假
  • scrollIntoView 应该向任何方向滚动。您可以将 URL 分享到不是这种情况的页面吗?

标签: javascript python selenium


【解决方案1】:

您可以尝试以下代码向上滚动页面:

from selenium.webdriver.common.keys import Keys

self.web_driver.find_element_by_tag_name('body').send_keys(Keys.HOME)

另一种方式(首选)您可以向上滚动到所需的元素:

element = self.web_driver.find_element_by_xpath('SOME_XPATH') # you can use ANY way to locate element
coordinates = element.location_once_scrolled_into_view # returns dict of X, Y coordinates
self.web_driver.execute_script('window.scrollTo({}, {});'.format(coordinates['x'], coordinates['y']))

【讨论】:

  • location_once_scrolled_into_view 不是默认将元素滚动到视图中然后返回坐标吗?为什么要再次调用execute_script('window.scrollTo())
  • 我不确定,但似乎该属性已更改,因此在上一个版本中它只返回 X、Y 坐标而不滚动到元素
  • 如果定义被认为是Use this to discover where on the screen an element is so that we can click it. This method should cause the element to be scrolled into view.,并且在没有滚动的情况下调用click(),该方法对我来说也没有任何意义。
  • @DebanjanB,这是初始描述,只有在if self._w3c返回True时才能执行滚动,但WebElement对象的默认值为self._w3c = False,所以else块由默认 - 不滚动
  • @Andersson 在第一次欣喜若狂之后,我发现您的解决方案并不是真的很好。因为它比以前的代码工作得更好,但并没有真正向上滚动......我需要调试以查看在我的代码中什么以及为什么不能正常工作。问题是这不是我的代码,而是一个在我之前在这里工作的人的代码,给我留下了那个奇怪的代码......
【解决方案2】:

这些年来我发现了一个handy tricky hacky stuff(我已经使用 Selenium 150 年了)。

当您无法向上滚动表单时,只需将键发送到页面顶部的输入。驱动程序会找到它并自动向上滚动页面以执行操作。

每当我想到这个技巧时,我就意识到做一个老人并不是那么糟糕。

祝你新水手好运,在塞莱尼亚海岸见。

【讨论】:

    【解决方案3】:

    试试这个,效果不错:

    view_port_height = "var viewPortHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);"
    element_top = "var elementTop = arguments[0].getBoundingClientRect().top;"
    js_function = "window.scrollBy(0, elementTop-(viewPortHeight/2));"
    
    scroll_into_middle = view_port_height + element_top + js_function
    
    driver.execute_script(scroll_into_middle, element)
    

    【讨论】:

    • 我不再在那里工作,所以我什至无法尝试这个解决方案 :) 但还是谢谢!
    【解决方案4】:

    这对我很有用:

    WebElement scrolling = new WebDriverWait(driver, 10)
                .until(ExpectedConditions.visibilityOfElementLocated(By.className("classSomething")));
    
    //SCroll Down
    ((JavascriptExecutor) driver).executeScript("arguments[0].scrollTo(0, arguments[0].scrollHeight)", scrolling);
    
    //Scroll Up
    ((JavascriptExecutor) driver).executeScript("arguments[0].scrollTo(0, arguments[0].scrollUp)", scrolling);
    

    【讨论】:

      【解决方案5】:

      getBoundingClientRect()scrollTo() 也可以这样做

      self.web_driver.execute_script("coordinates = arguments[0].getBoundingClientRect();scrollTo(coordinates.x,coordinates.y);", element)
      

      我测试过,它会上下波动。

      【讨论】:

      • 仅供参考 Python 属性 location_once_scrolled_into_view 与 JavaScript getBoundingClientRect() 方法所做的完全相同
      【解决方案6】:

      如果您将驱动程序定义为webdriver.Chrome()webdriver.Firefox(),则可以使用此代码向上滚动:

      from selenium.webdriver.common.keys import Keys
      driver.find_element_by_tag_name('body').send_keys(Keys.HOME)
      

      此外,对于向下滚动,您可以尝试以下代码:

      driver.execute_script("arguments[0].scrollTop = arguments[0].scrollHeight", scr1)
      

      scr1 是您要滚动的框 xpath。 您也可以通过此代码滚动到页面中间:

      driver.execute_script("arguments[0].scrollTop = arguments[0].scrollWidth", scr1)
      

      【讨论】:

        【解决方案7】:

        对于 java,我使用下一个表达式:

          WebElement element = drv.findElement(By.xpath("//div"));
          (drv as JavascriptExecutor).executeScript("arguments[0].scrollIntoView();", element);
        

        sn-p 向下滚动到 Selenium 中的一个元素,直到它可见

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-11-01
          • 2018-06-22
          • 1970-01-01
          • 1970-01-01
          • 2019-09-28
          • 1970-01-01
          • 1970-01-01
          • 2018-08-09
          相关资源
          最近更新 更多