Selenium 只找到非隐藏和非禁用的项目?

Selenium find Only non-hidden and non disabled items?

我在python中写道:

login_forms = driver.find_elements(by=By.TAG_NAME, value='form')

这非常适合在页面中获取所有表单。然后我以这样的形式遍历所有输入:

form_inputs = login_forms[0].find_elements(by=By.TAG_NAME, value='input')

我怎样才能只找到没有隐藏或禁用的项目(普通用户可以看到并篡改或纠正他自己的价值)?


建议的代码(对我不起作用):

login_forms = driver.find_elements(by=By.TAG_NAME, value='form')


for login_form in login_forms:
        clean_form_inputs = login_form.find_elements(By.XPATH, "//input[not @disabled and(not(contains(@class,'disabled'))) and(not(contains(.,'display: none')))]")
        if len(clean_form_inputs) < 2:
            continue
        print(str(len(clean_form_inputs)))

我得到:

selenium.common.exceptions.InvalidSelectorException: Message: invalid selector: Unable to locate an element with the xpath expression //[not @disabled and(not(contains(@class,'disabled'))) and(not(contains(.,'display: none')))] because of the following error: SyntaxError: Failed to execute 'evaluate' on 'Document': The string '//[not @disabled and(not(contains(@class,'disabled'))) and(not(contains(.,'display: none')))]' is not a valid XPath expression. (Session info: chrome=99.0.4844.83)

这取决于表单的隐藏或禁用方式:

  1. 是使用特定class启用或禁用

    的表格
  2. 可以用css值来决定是否隐藏

  3. 内置方法 isvisible 和 isEnabled 是否有效等,如果是这样,找到所有元素,然后遍历每个元素并过滤给出 isvisible 或 isenabled 为 true 的元素

    print([元素在 driver.find_elements(*locator) 如果(element.is_displayed())])

查看所有可用方法:

https://www.selenium.dev/selenium/docs/api/py/webdriver_remote/selenium.webdriver.remote.webelement.html#selenium.webdriver.remote.webelement.WebElement.is_displayed

去给你一个正确的答案我们需要知道如何定义隐藏和禁用的块和元素。
我可以假设禁用元素将具有 disabled 属性或 disabled class 名称,而隐藏块将具有 display: none 样式值或 type="hidden".
如果是这样,我们可以定义定位器来定位所有未禁用且未隐藏的元素,如下所示:

"//*[not(@disabled) and(not(contains(@class,'disabled'))) and(not(contains(.,'display: none'))) and(not(@type='hidden'))]"

使用 Selenium find_elements 它看起来像:

visible_enabled_elements = driver.find_elements(By.XPATH, "//*[not(@disabled) and(not(contains(@class,'disabled'))) and(not(contains(.,'display: none'))) and(not(@type='hidden'))]")

但此实现取决于您正在处理的网站上禁用和隐藏元素的确切程度,因为它可能有所不同。
UPD
无需组合 By.XPATHBy.TAG_NAME,因为 By.XPATH 已经包含元素标签名称。
在上面的示例中,我使用 //* 来定位所有标签名称,但是如果您只想 select input 元素,例如它将是:

visible_enabled_elements = driver.find_elements(By.XPATH, "//input[not(@disabled) and(not(contains(@class,'disabled'))) and(not(contains(.,'display: none'))) and(not(@type='hidden'))]")