无法使用 Selenium 和 Python 在#shadow-root(打开)中找到登录元素
Unable to locate the Sign In element within #shadow-root (open) using Selenium and Python
我正在尝试使用 selenium 自动执行某些操作,但无法在页面上找到第一个元素 https://developer.servicenow.com/dev.do,因此无法登录
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver_path = "../bin/chromedriver.exe"
driver = webdriver.Chrome(driver_path)
driver.get("https://developer.servicenow.com/dev.do")
driver.find_element_by_xpath("/html/body/dps-app//div/header/dps-navigation-header//header/div/div[2]/ul/li[3]/dps-login//div/dps-button//button/span")
我收到错误
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"/html/body/dps-app//div/header/dps-navigation-header//header/div/div[2]/ul/li[3]/dps-login//div/dps-button//button/span"}
我认为这是因为您试图在网站有时间加载所有元素之前访问“登录”。
我建议你使用
driver.set_page_load_timeout(120)
所以 selenium 会在网站上加载所有内容后寻找按钮。
要登录按钮在多个#shadow-root (open)
解决方案
Tto click()
你可以在你想要的元素上使用 shadowRoot.querySelector()
并且你可以使用下面的 :
from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_argument("start-maximized")
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('useAutomationExtension', False)
driver = webdriver.Chrome(options=options, executable_path=r'C:\WebDrivers\chromedriver.exe')
driver.get('https://developer.servicenow.com/dev.do')
SignInButton = driver.execute_script("return document.querySelector('dps-app').shadowRoot.querySelector('dps-navigation-header').shadowRoot.querySelector('header.dps-navigation-header dps-login').shadowRoot.querySelector('dps-button')")
SignInButton.click()
- 浏览器快照:
参考资料
您可以在以下位置找到一些相关的详细讨论:
您可以查看 servicenow 商店中的 Automatepro 应用程序。它使用 selenium,但他们已经在幕后预先编写了 selenium 以与所有 servicenow UI 组件交互,包括那些使用 shadow DOM 的组件。您只需选择 UI 元素并为您的测试提供数据。我们发现它节省了大量自己编写和维护 selenium 代码的时间..
这个解决方案正是我使用 Powershell 登录我的实例所寻找的解决方案。
driver.executescript("return document.querySelector('dps-app').shadowRoot.querySelector('dps-navigation-header').shadowRoot.querySelector('header.dps-navigation-header dps-login').shadowRoot.querySelector('dps-button')").Click()
我正在尝试使用 selenium 自动执行某些操作,但无法在页面上找到第一个元素 https://developer.servicenow.com/dev.do,因此无法登录
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver_path = "../bin/chromedriver.exe"
driver = webdriver.Chrome(driver_path)
driver.get("https://developer.servicenow.com/dev.do")
driver.find_element_by_xpath("/html/body/dps-app//div/header/dps-navigation-header//header/div/div[2]/ul/li[3]/dps-login//div/dps-button//button/span")
我收到错误
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"/html/body/dps-app//div/header/dps-navigation-header//header/div/div[2]/ul/li[3]/dps-login//div/dps-button//button/span"}
我认为这是因为您试图在网站有时间加载所有元素之前访问“登录”。
我建议你使用
driver.set_page_load_timeout(120)
所以 selenium 会在网站上加载所有内容后寻找按钮。
要登录按钮在多个#shadow-root (open)
解决方案
Tto click()
你可以在你想要的元素上使用 shadowRoot.querySelector()
并且你可以使用下面的
from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_argument("start-maximized")
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('useAutomationExtension', False)
driver = webdriver.Chrome(options=options, executable_path=r'C:\WebDrivers\chromedriver.exe')
driver.get('https://developer.servicenow.com/dev.do')
SignInButton = driver.execute_script("return document.querySelector('dps-app').shadowRoot.querySelector('dps-navigation-header').shadowRoot.querySelector('header.dps-navigation-header dps-login').shadowRoot.querySelector('dps-button')")
SignInButton.click()
- 浏览器快照:
参考资料
您可以在以下位置找到一些相关的详细讨论:
您可以查看 servicenow 商店中的 Automatepro 应用程序。它使用 selenium,但他们已经在幕后预先编写了 selenium 以与所有 servicenow UI 组件交互,包括那些使用 shadow DOM 的组件。您只需选择 UI 元素并为您的测试提供数据。我们发现它节省了大量自己编写和维护 selenium 代码的时间..
这个解决方案正是我使用 Powershell 登录我的实例所寻找的解决方案。
driver.executescript("return document.querySelector('dps-app').shadowRoot.querySelector('dps-navigation-header').shadowRoot.querySelector('header.dps-navigation-header dps-login').shadowRoot.querySelector('dps-button')").Click()