Selenium将按钮标识为可单击,但不可用

2024-10-03 15:21:51 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个问题,Selenium说按钮即使被禁用也可以点击

我在一个网站上使用Selenium,在点击“Book”按钮之前,你必须先从下拉列表中选择一个日期,然后选择一个时间段,这样你就可以做任何事情。在选择日期和时间段之前,按钮元素是

<div id="pt1:b2" class="x28o xfn p_AFDisabled p_AFTextOnly" style="width:300px;" _afrgrp="0" role="presentation"><a data-afr-fcs="false" class="xfp" aria-disabled="true" role="button"><span class="xfx">Book</span></a></div>

选择日期和时间段后,按钮变为

<div id="pt1:b2" class="x28o xfn p_AFTextOnly" style="width:300px;" _afrgrp="0" role="presentation"><a href="#" onclick="this.focus();return false" data-afr-fcs="true" class="xfp" role="button"><span class="xfx">Book</span></a></div>

我正在尝试使用此代码等待按钮可单击

wait = WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable((By.ID, 'pt1:b2')))

但Selenium表示,即使没有选择日期或时间段,而且按钮完全变灰且不可点击,在网站加载后,按钮几乎可以立即点击。在导航到url并等待按钮可点击后,我通过检查时间戳对此进行了测试,几乎没有延迟。我已经手动求助于try-except循环,并在这两个循环之间休眠,以便能够成功单击按钮,但我更愿意找出导致此问题的原因。有什么想法吗


Tags: divid网站selenium按钮b2classrole
3条回答

解决这个问题的方法是只搜索要更改的类属性,而不是搜索要单击的元素

wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div[class='x28o xfn p_AFTextOnly']")))

Selenium isclickable检查是否显示isdisplayed并启用检查单击能力

和isdisplay检查样式属性,但isenabled检查禁用属性

现在disable在大多数情况下不是通过html disable属性处理的,而是通过javascript和css类处理的

所以可点击条件在这些情况下不起作用

https://www.selenium.dev/selenium/docs/api/py/webdriver_support/selenium.webdriver.support.expected_conditions.html

因此,在这种情况下,单击不会抛出错误

https://github.com/SeleniumHQ/selenium/blob/trunk/py/selenium/common/exceptions.py

如果您检查exception类,您可以看到exception仅存在于not visible中,请单击intercepted和not enabled

元素可点击()

^{}是检查元素是否可见并启用以便可以单击它的期望值。它是defined作为:

def element_to_be_clickable(locator):
    """ An Expectation for checking an element is visible and enabled such that
    you can click it."""
    def _predicate(driver):
    element = visibility_of_element_located(locator)(driver)
    if element and element.is_enabled():
        return element
    else:
        return False

    return _predicate
    

现在,即使在没有选择日期或时间段的情况下加载网站时,属性的值p_AFDisabled的存在决定了元素是启用还是禁用。接下来,当您填写日期或时间段时,属性的值p_AFDisabled将被删除,元素将变得可单击

因此,理想情况下,要等待按钮可点击,您需要为element_to_be_clickable()诱导WebDriverWait,并且您可以使用以下任一Locator Strategies

  • 使用CSS_SELECTOR

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div.p_AFTextOnly > a[onclick] > span.xfx"))).click()
    
  • 使用XPATH

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[contains(@class, 'p_AFTextOnly')]/a[@onclick]/span[text()='Book']"))).click()
    
  • 注意:您必须添加以下导入:

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

相关问题 更多 >