selenium.common.exceptions.ElementNotVisibleException:消息:尝试使用 Python + Selenium 访问元素时元素不可见

selenium.common.exceptions.ElementNotVisibleException: Message: element not visible while trying to access an element with Python + Selenium

我正在尝试在以下网站中输入用户名和密码: https://www.thegreatcoursesplus.com/sign-in

driver = webdriver.Chrome()
driver.get('https://www.TheGreatCoursesPlus.com/sign-in')
driver.find_element_by_xpath('//h1[@class="sign-in-input"]').click()

这给出了以下异常:

selenium.common.exceptions.ElementNotVisibleException: Message: element not visible

然后我尝试使用 java 脚本:

driver.execute_script("document.getElementsByClassName('sign-in-input')[0].click()")
cmd = "document.getElementsByClassName('label-focus')[0].value = 'abc@abc.com'"
driver.execute_script(cmd)

没有错误,但没有文本发送到“电子邮件地址”字段。

谁能指导我输入电子邮件地址和密码的正确方法,然后单击“登录”。

用户名使用:

driver.find_element_by_xpath("//input(@type='email')").click()
driver.find_element_by_xpath("//input(@type='email')").send_keys( "username" )

密码使用:

driver.find_element_by_xpath("//input(@type='password')").click()
driver.find_element_by_xpath("//input(@type='password')").send_keys( "password" )

这个错误信息...

selenium.common.exceptions.ElementNotVisibleException: Message: element not visible

...意味着 元素在 HTML DOM 中不可见 WebDriver 实例试图找到它。


ElementNotVisibleException

ElementNotVisibleException is thrown when an element is present on the DOM Tree,但它不可见,因此无法与之交互。


原因

ElementNotVisibleException 的一个积极因素是 WebElement 存在 HTML 并且在尝试 click()read 从视图中隐藏的元素属性时通常会遇到此异常。


解决方案

As ElementNotVisibleException 确保 WebElement present 在 HTML 中因此,按照下面详述的后续步骤,前面的解决方案将是两倍:

  • 如果下一步是读取所需元素的任何属性,则需要按如下方式归纳WebDriverWait in-conjunction with expected_conditions clause set to visibility_of_element_located

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    
    my_value = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.XPATH, "element_xpath"))).get_attribute("innerHTML")
    
  • 如果下一步是在所需元素上调用 click(),则需要按如下方式引入 WebDriverWait in-conjunction with expected_conditions clause set to element_to_be_clickable

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    
    WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "element_xpath"))).click()
    

这个用例

您构造为 //h1[@class="sign-in-input"]xpath 不匹配任何节点。我们需要创建唯一的 xpath 来定位代表 Email AddressPasswordSign In 按钮的元素 WebDriverWait.下面的代码块将帮助您实现相同的目标:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

options = Options()
options.add_argument("start-maximized")
options.add_argument("disable-infobars")
options.add_argument("--disable-extensions")
driver = webdriver.Chrome(chrome_options=options, executable_path="C:\Utility\BrowserDrivers\chromedriver.exe")
driver.get('https://www.TheGreatCoursesPlus.com/sign-in')
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//div[@id='modal']//input[@name='email']"))).send_keys("abc@abc.com")
driver.find_element_by_xpath("//div[@id='modal']//input[@name='password']").send_keys("password")
driver.find_element_by_xpath("//div[@id='modal']//button[@class='color-site sign-in-button']").click()

有两个问题:

  • 第一个是时间,表格出现需要一些时间。您可以使用显式等待来解决它。
  • 第二个是<input>标签里的字段id,不是<h1>标签里的字段id,匹配这个xpath的字段有很多。我建议您找到包含字段的表单并使用它来定位每个字段

对于时间问题,您可以使用显式等待

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Chrome()
driver.get('https://www.TheGreatCoursesPlus.com/sign-in')
form = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.XPATH, '//div[@class="modal-body"]//form')))

form.find_element_by_name('email').send_keys(email)
form.find_element_by_name('password').send_keys(password)
form.find_element_by_name('sign-in-button').click()