【问题标题】:Scrolling to an element in Selenium滚动到 Selenium 中的元素
【发布时间】:2018-05-24 12:43:11
【问题描述】:

我正在使用 selenium 来抓取动态网站。我的问题是我无法向下滚动到我正在寻找的项目。首先,我列出了我想从 (python_button1) 获取信息的那些项目。我必须单击此列表中的每个项目才能看到一个新窗口,我想在其中抓取它们。然后我做了一个循环来点击这些项目。之后,我关闭了我打开的窗口。不幸的是,我无法向下滚动到每个项目以单击它们。我使用了以下代码,但它向下滚动到最后一项并跳过其他项目。如果您能帮助我,我将不胜感激。谢谢!

python_button1 = driver.find_elements_by_class_name('simboloEvento')

for x in python_button1:
    x.click()
    time.sleep(2)
    driver.find_element_by_class_name('cerrarBoton').click() 
    driver.execute_script("coordinates=arguments[0]. 
    getBoundingClientRect();scrollTo( coordinates.x,coordinates.y);", x)
    time.sleep(2)


innerHTML = driver.execute_script("return document.body.innerHTML")
print(innerHTML)

向下滚动列表是一个 JavaScript 对象。我必须单击每个对象来激活 javascript 函数(一个新窗口)。我可以通过我的代码激活这些对象,但问题是当这些项目中的至少一个不在当前屏幕中时。这就是为什么我应该首先向下滚动到该对象(此处为 x)以便能够单击它。但我不知道如何向下滚动到该对象。我已经使用了我在这篇文章中使用的代码以及这个:driver.execute_script("arguments[0].scrollIntoView();", x) 但它们都不适合我!

【问题讨论】:

  • 向下滚动列表是 JavaScript 对象吗?
  • 请显示HTML(不要使用截图)和项目截图
  • 是的,向下滚动列表是一个 JavaScript 对象。我必须单击每个对象来激活 javascript 函数(一个新窗口)。我可以通过我的代码激活这些对象,但问题是当至少其中一个项目不在当前屏幕中时。这就是为什么我应该首先向下滚动到该对象(此处为 x)以便能够单击它。但我不知道如何向下滚动到该对象。我已经使用了我在这篇文章中使用的代码以及这个:driver.execute_script("arguments[0].scrollIntoView();", x) 但它们都不适合我!

标签: python selenium


【解决方案1】:

为此,您需要两件事。首先知道元素在哪里,你可以像这样用 python-js 做到这一点:

script = 'return arguments[0].getBoundingClientRect().top + document.documentElement.scrollTop;'
posY = driver.execute_script(script, element).split('.')[0]

上述组合将返回一个字符串,该字符串表示元素与文档(网站)顶部的相对位置

然后你可以滚动到你想要的位置

driver.execute_script('window.scrollTo(0, '+ posY +');')

这个会移动元素所在的屏幕,需要等待一些元素,所以我建议一些这种性质的等待功能:

def waiter(token):
    # token is whatever you spect to be in the element like str("/") in a date field
    max_time = 60 #segs
    driver.switch_to.default_content()

    while token not in driver.find_element_by_xpath('//*[@Class="important"]'):
        time.sleep(1)
        max_time += -1
        if max_time == 0:
            raise Exception('Waited too long')

用 js 导航给自己做了一个小模块,因为即使 selenium 功能强大,有时它也不想在某些网站上这样做。

编辑: 为了完整起见,这个 sn-p 使元素可见:

driver.execute_script(“arguments[0].style.visibility = 'visible';”, element)

这是有效的,因为arguments[0] 代表execute_script 中的element 参数

【讨论】:

  • 如果您不介意,请告诉我您是如何添加 js_in 的。我想运行代码,但 js_in 未定义。谢谢!
  • @Morishah 我已经编辑了代码,js_in 是你传递给execute_script 的脚本,所以我把它重命名为script
  • 我已经尝试过了,只要新窗口不覆盖循环中的下一个对象,它就可以工作。当我单击对象时,我想从中获取数据的新窗口会激活,但它会覆盖下一个对象,这就是我无法单击下一个对象的原因。我不知道如何解决这个问题。这是错误:NoSuchElementException:没有这样的元素:无法找到元素:...谢谢!
  • @Morishah 但这就是你问的。那是另一个问题。为此,您需要确保元素是可见的,js 也是可行的
  • 你能告诉我如何使元素可见吗?谢谢!
【解决方案2】:

您是否尝试过使用 selenium 操作类?

builder = ActionChains(驱动程序)
builder.move_to_element(x).perform()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-01
    • 1970-01-01
    • 2021-01-28
    • 1970-01-01
    • 2018-08-09
    • 1970-01-01
    • 2017-01-03
    • 2014-10-14
    相关资源
    最近更新 更多