在 driver.execute_script() 中使用伪选择器时无法将某些元素滚动到视图中

Posted

技术标签:

【中文标题】在 driver.execute_script() 中使用伪选择器时无法将某些元素滚动到视图中【英文标题】:Unable to scroll some element into view while using pseudo selector within driver.execute_script() 【发布时间】:2020-05-06 15:43:12 【问题描述】:

我创建了一个脚本,使用 selenium 来获取动态生成的文本。这是我使用硒的要求,所以在这种情况下我不想去 xhr 。我正在尝试在 selenium 中使用 pseudo selector 在其中定义 explicit wait 。由于 selenium 不支持pseudo selector,如:contains(),我使用javascript 命令driver.execute_script() 来达到目的。

现在,我尝试的方式不一致,因为我要抓取的文本不在视口中。如果我在脚本运行时手动向下滚动一点,它就可以工作。顺便说一下,Xpath 在这里不是一个选项。

如何在 driver.execute_script() 中使用伪选择器时将元素滚动到视图中?

我尝试过 [工作不一致]:

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait

with webdriver.Chrome() as driver:
    wait = WebDriverWait(driver, 10)
    driver.get('https://www.nyse.com/quote/XNYS:AAN')

    item = wait.until(
        lambda driver: driver.execute_script('''return $('span:contains("AARONS")')[0];''')
    )
    print(item.text)

预期结果:

AARONS INC

PS 在将此帖子标记为重复之前,请确保您至少阅读了问题的标题。

【问题讨论】:

我看到的问题是span 元素实际上并不包含文本AARONS INC,除非您检查该元素并尝试在devtools 中展开span 元素。 在运行脚本时向下滚动一点,问题就不再存在了。然而问题是我没有找到将元素带入视口的任何想法。 不幸的是,我正在使用该网站在本地进行测试,即使在将 AARONS INC 滚动到视口后(通过滚动到 Quote 标题),span 仍然不包含 AARONS INC 文本-- 我等待了 15 秒,但从未找到该元素。 请查看此 video link 以消除任何混淆@Christine。 我无法清楚地理解您想要做什么。我无需手动滚动即可执行您的代码,并且可以正常工作。 【参考方案1】:

您可以使用返回的WebElement 执行另一个 JavaScript 命令

item = wait.until(
    lambda d: d.execute_script('''return $('span:contains("AARONS")')[0];''')
)

driver.execute_script('arguments[0].scrollIntoView();', item)

或在单个脚本中

item = wait.until(
    lambda d: d.execute_script(
        '''var el = $('span:contains("AARONS")')[0];
        if (typeof el !== "undefined") 
            el.scrollIntoView();
        
        return el;''')
)

这将等到元素存在并将其滚动到视图中。

【讨论】:

感谢您的回答@Guy。我的问题实际上是针对您的第二个答案。但是,它会抛出此错误raise exception_class(message, screen, stacktrace) selenium.common.exceptions.JavascriptException: Message: javascript error: Cannot read property 'scrollIntoView' of undefined 这对于这个史诗般的答案来说太少了。我将尝试在不同的情况下查看它的行为方式。非常感谢。我认为第一个答案无济于事,因为它会在到达此行之前抛出错误driver.execute_script('arguments[0].scrollIntoView();', item) @MITHU 第一个也会等待元素,只是不会滚动。如果您看到超时异常,您可以增加WebDriverWait 中的时间。【参考方案2】:

您也可以通过识别 CSS 元素来尝试

创建一个带有 CSS 参数的通用方法,并且可以重用它

script = "document.querySelector('#css_selector').scrollIntoView(true);"

driver.execute_script(script)

【讨论】:

以上是关于在 driver.execute_script() 中使用伪选择器时无法将某些元素滚动到视图中的主要内容,如果未能解决你的问题,请参考以下文章

js加载页面使用execute_script选定加载位置

iOS 滑动比较

python之selenium调用js(execute_script)

selenium 页面滚动操作

如何获取 Instagram 图片详细信息

python网络爬虫:Selenium