不允许使用 Selenium 化合物类名

问题描述 投票:0回答:5

我有下面的代码,单击一个元素会弹出一个屏幕并复制其中的文本

el1 = driver.find_element_by_id("keyDev-A")
el1.click()
el2 = driver.find_element_by_class_name("content")
print(el2.text)

但是,当我尝试让

selenium
单击该弹出窗口中的按钮时

el3 = driver.find_element(By.CLASS_NAME, "action-btn cancel alert-display")
el3.click()

它会产生一条错误消息:

invalid selector: Compound class names not permitted

这是我试图让

selenium
单击的 HTML。
Close
按钮。

<div class="nav">
    <span class="action-btn confirm prompt-display">Confirm</span>
    <span class="action-btn cancel prompt-display">Cancel</span>
    <span class="action-btn cancel alert-display">Close</span>
</div>

我应该如何书写

el3
才能单击 关闭 按钮?

python selenium xpath css-selectors class-names
5个回答
67
投票

Leon 的评论 提供了不再支持复合类名的正确信息。您可以尝试使用 css 选择器。对于您的情况,以下代码行应该可以帮助您获得所需的元素:

el3 = driver.find_element_by_css_selector(".action-btn.cancel.alert-display")

对于较新的 Selenium 版本

el3 = driver.find_element(By.CSS_SELECTOR, ".action-btn.cancel.alert-display")

它在 class 属性中查找具有所有三个类(action-btn、cancel 和alert-display)的元素。请注意,类的顺序在这里并不重要,任何类都可能出现在类属性中的任何位置。只要该元素具有所有三个类,它就会被选择。 如果您希望固定类的顺序,可以使用以下 xpath :

el3 = driver.find_element_by_xpath("//*[@class='action-btn cancel alert-display']") 

3
投票

这个问题我迟到了。但当您不熟悉 Xpath 时,我还找到了一种解决方法,即使用 tag_name 和 get_attribute('class') 将复合类视为字符串。它需要更多行代码,但它很简单,适合像我这样的初学者。

   elements = driver.find_elements_by_tag_name('Tag Name Here')
        for element in elments:
            className = watchingTable.get_attribute('class')
            print(className)
                if className == 'Your Needed Classname':
                    #Do your things

1
投票

这里的答案不正确:

如果您检查 by_class_name 中的异常:

你可以看到它在幕后使用CSS

by_class_name 只是添加 '.'在提供的定位器前面,因此 'a' 将作为 '.a' 传递,a.b 将作为 '.a.b' 传递

所以你可以对多个类使用class_name,只需要将空格替换为“.”

所以“a b c”应该作为“a.b.c”传递

例如:

工作示例:

from selenium import webdriver

import time

from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Chrome()
driver.get("https://stackoverflow.com/questions/65579491/find-element-by-class-name-in-selenium-giving-error/65579606?noredirect=1#comment115946541_65579606")
time.sleep(5)
elem = driver.find_element_by_class_name('overflow-x-auto.ml-auto.-secondary.grid.ai-center.list-reset.h100')

print(elem.get_attribute("outerHTML"))

0
投票

这个错误信息...

invalid selector: Compound class names not permitted

...意味着使用复合类名定位器策略在使用Selenium时无效。

此更改的痕迹可以从 Selenium v2.40.0 更改列表中确认,其中更改日志提到为复合类名使用添加正确的错误代码:

  • 针对无效 css 选择器空类名和原子中的复合类名的情况实现了正确的错误代码。

解决方案

作为替代方案,您可以使用以下任一定位器策略

  • 使用

    CSS_SELECTOR

    driver.find_element(By.CSS_SELECTOR, "span.action-btn.cancel.alert-display").click()
    
  • 使用

    XPATH

    driver.find_element(By.XPATH, "//span[@class='action-btn cancel alert-display']").click()
    

参考文献

您可以在以下位置找到一些相关的详细讨论:


0
投票

手动交叉多个类的结果。

def find_element_multi_class(driver, classes):
    elements = []
    for i,c in enumerate(classes):
        if i == 0:
            elements = driver.find_elements(By.CLASS_NAME, c)
        else:
            new_elems = driver.find_elements(By.CLASS_NAME, c)
            elements = list(set(elements) & set(new_elems))
    return elements
© www.soinside.com 2019 - 2024. All rights reserved.