selenium.common.exceptions.ElementNotVisibleException:消息:元素不可交互且显式等待不适用于Selenium和Python

时间:2019-02-03 15:32:07

标签: python selenium selenium-webdriver css-selectors webdriverwait

我正在尝试访问PenFed,以获取当前的未付款项。我已经做了很多研究,但不幸的是,我仍然感到困惑。我正在使用Python Selenium,并且尝试单击侧面的初始登录按钮以查看用户名字段。这是元素的HTML代码:

<a href="https://www.penfed.org/" class="pfui-button-login login-slide-button pfui-button pfui-btn-tertiary-dark-blue-outline" id="mobile-login" data-di-id="#mobile-login">Login</a>

当我尝试运行以下代码时:

driver.find_element_by_id("mobile-login").click()

我收到以下错误:

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

即使当我尝试使用WebDriver Wait功能时,例如:

try:
    WebDriverWait(driver, 5).until(EC.visibility_of_element_located((By.ID, "mobile-login"))).click()
except ElementNotVisibleException:
    WebDriverWait(driver, 5).until(EC.element_to_be_clickable((By.ID, "mobile-login"))).click()

无论我让他们等待多长时间,我都会收到一条超时消息:

raise TimeoutException(message, screen, stacktrace) selenium.common.exceptions.TimeoutException: Message:

我所有的研究都表明,调用等待功能应该可以解决该问题,但对我而言不起作用。我还读到,在单击按钮之前,我必须调用该元素上方的图像叠加层,但是在网站代码中也看不到任何内容。如果要对其进行测试,则能够通过代码单击按钮的唯一方法是首先物理单击它,因此我不知道可以使用其他任何方法。预先感谢您的帮助!

更新:我发现以下代码对我有用:

element = driver.find_element_by_id("mobile-login")
driver.execute_script("$(arguments[0]).click();", element)

但是我不知道execute_script实际上是做什么的。有人可以解释这段代码是否有效,或者是否有其他替代方法适用于他们?

3 个答案:

答案 0 :(得分:0)

您指定的代码为JQueryexecute_script(p1, p2)运行一个js脚本,其中p1是脚本(在您的情况下为单击元素的JQuery行),而p2是所需的元素。如果arguments[0]等于“ element”,您似乎不需要p2,但是我不确定。

一种可能的解决方法是使用计数器作为单击元素的次数。如果计数器达到一定数量并且页面没有更改(您可以通过在当前页面上找到唯一的元素/值进行检查),则表明它不可单击。

祝你好运!

答案 1 :(得分:-1)

所需元素是动态元素,因此要定位该元素,必须使 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-extensions')
    driver = webdriver.Chrome(chrome_options=options, executable_path=r'C:\WebDrivers\chromedriver.exe')
    driver.get('https://www.penfed.org/')
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.pfui-button.login-slide-button.pfui-button-login.dtm-global-nav[data-id='Open Log In Drawer']"))).click()
    
  • 浏览器快照:

penfed.org

答案 2 :(得分:-1)

您尝试单击的链接是针对移动网站的,如果您以桌面分辨率查看该网站,则该链接不可见。如果缩小浏览器直到其更改布局,您将看到与该链接相对应的“登录”按钮出现。这就是为什么您得到ElementNotVisibleException的原因。

关于第二个问题,使用.execute_script()的原因是它可以直接执行JS,并且可以单击任何隐藏或不隐藏的内容。 Selenium旨在与用户进行页面交互,因此不会让您单击不可见的元素等。 如果您打算让脚本像用户一样操作,则应避免使用.execute_script(),因为它允许您在用户无法执行的页面上执行操作。

如果要像台式机用户一样登录,则需要使用下面的CSS选择器单击“登录”按钮

button[data-id='Open Log In Drawer']

这将打开一个侧面板,您可以在其中输入用户名等,然后登录。仅供参考...您可能需要等待,以便有机会打开面板,然后再继续登录过程。