不允许使用硒化合物类名称

Posted

技术标签:

【中文标题】不允许使用硒化合物类名称【英文标题】:Selenium Compound class names not permitted 【发布时间】:2016-10-12 19:13:08 【问题描述】:

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

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 点击的 htmlClose 按钮。

<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才能点击关闭按钮?

【问题讨论】:

你见过***.com/questions/10658907/… 吗?这可能会有所帮助。 Selenium 不支持带有复合类BY.CLASS_NAME..您需要使用cssSelectorXPath 在这里找到el3... How to avoid Compound Class name error in Page Object?的可能重复 【参考方案1】:

Leon's comment 导致不再支持复合类名称的正确信息。你可以做的是尝试使用 css 选择器。在您的情况下,以下代码行应该可以帮助您获得所需的元素:

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

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

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

【讨论】:

【参考方案2】:

这个问题我迟到了。但是,当您不熟悉 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

【讨论】:

这种方式使用一段时间后。我发现这可能不是一个好的解决方案。因为当 TagName 是 'DIV' 或 'SPAN' 时,每次尝试定位过重的元素时都必须遍历整个文档。此外,当页面加载时,您可能需要添加一些 Try except 错误句柄来摆脱烦人的异常。学习并熟悉 sagarwadhwa1 的回答建议将是很好的做法。【参考方案3】:

这里的答案不正确:

如果您从 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://***.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"))

【讨论】:

【参考方案4】:

此错误消息...

invalid selector: Compound class names not permitted

...暗示使用Compound class names 的locator strategies 在使用Selenium 时无效。

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

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

解决方案

您也可以使用以下任一Locator Strategies:

使用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()

参考文献

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

How to locate an element with multiple classnames using Selenium and Python

【讨论】:

以上是关于不允许使用硒化合物类名称的主要内容,如果未能解决你的问题,请参考以下文章

在属性类名称之前的C#中使用了什么是new关键字?

让用户不关注硒

使用 Castle ActiveRecord,当两个类名称相同但名称空间不同时,我会收到 NHibernate DuplicateMappingException

“类名称”+“::”调用方式

逃避检测硒自动化

DTracing objc_msgSend 不打印接收器类名称