Selenium python find_element_by_class_name() 从 v 2.2 到 2.21 停止工作——不能使用“复合类名”
Posted
技术标签:
【中文标题】Selenium python find_element_by_class_name() 从 v 2.2 到 2.21 停止工作——不能使用“复合类名”【英文标题】:Selenium python find_element_by_class_name() stopped working from v 2.2 to 2.21 -- cannot use 'Compound Class Name' 【发布时间】:2012-05-26 09:33:54 【问题描述】:我正在使用 Selenium 的 python 库从 Firefox 的 html 页面中抓取数据。
我不得不从 Selenium 2.0 更新到 2.21,因为服务器已经更新了 Firefox。
在 v 2.21 中,对 find_element_by_class_name("grid-cell-inner grid-col-name")
的调用失败:
selenium.common.exceptions.WebDriverException: Message: u'Compound class names not permitted'
我试图访问的元素的类名是grid-cell-inner grid-col-name
对find_element_by_class_name()
的调用在v 2.2 中有效,所以逻辑是正确的,并且以前可以找到数据。 v 2.21 中发生了一些变化。
所有 Selenium 示例都给出了类名称为 foo
等的简单示例,没有我需要访问的名称类型。
为什么 Selenium 不再支持查找名称为 grid-cell inner grid-col-name
的类,以及他们的解决方案是什么?
有人可以帮我找到具有“复合”类名称的元素吗?
【问题讨论】:
【参考方案1】:WebDriver 的问题在于它仍在不断发展。很多。我个人不知道有哪个版本支持在一个命令中搜索多个类,所以它一定是一个相当古老的版本:)。
通过CSS selector 搜索应该可以,但是:
find_element_by_css_selector(".grid-cell-inner.grid-col-name");
我不建议将XPath 用于这个特定的东西,因为以下两个表达式是不同的东西:
//*[class='grid-cell-inner grid-col-name']
//*[class='grid-col-name grid-cell-inner']
【讨论】:
不是多类搜索;我无法控制的 html 中的类名中有空格。如果这是一个“复合类名”,那为什么要停止支持它呢?现在我们所有的逻辑都被打破了。 其实,没有。这是两个独立的课程,grid-cell-inner
和 grid-col-name
,我对此 100% 持肯定态度。我不知道 Selenium 不支持通过许多类名进行搜索的原因——但我想这就是 CSS 选择器的用途。如果它有效,它一定是某个 alpha 或 beta 版本,因为我在任何更新日志中都找不到任何提及。使用 CSS 选择器解决方案,应该可以。
A quick googling 说:要指定多个类,请用空格分隔类名,例如。这允许您为一个 HTML 元素组合多个 CSS 类。
是的。使用 find_element_by_css_selector() 并按照您的描述指定类名可以正常工作。我只需要更改几行代码即可支持这一点,现在我可以找到元素。非常感谢!【参考方案2】:
您需要使用格式为“.nameA.nameB.nameC”的 CssSelector,您可以拥有任意数量的 CssSelector,只需添加“.”即可
或者,您可以匹配整个属性(您也可以使用 xpath 执行此操作):“[class='exact class name here']” XPath - "//[@class='这里的确切类名']"
有一些方法可以以开头或以结尾或包含(在 CSS 和 xpath 中),如果类是动态生成。
【讨论】:
不应该是 "//*[@class='exact class name here']" 吗?强调 * 那么,*应该出现还是不出现?【参考方案3】:我想Selenium 很长时间不支持复合类名了。
不用说,尝试通过 XPath 或 CSS 选择器或通过“grid-cell-inner”类名,然后过滤以查看哪些元素具有“grid-cell-inner grid-col-name”类。
【讨论】:
【参考方案4】:也可以试试:
elements = bot.execute_script("""return document.getElementsByClassName('grid-cell-inner grid-col-name')""")
【讨论】:
【参考方案5】:此错误消息...
selenium.common.exceptions.WebDriverException: Message: u'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, ".grid-cell-inner.grid-col-name")
使用XPATH
:
driver.find_element(By.XPATH, "//*[@class='grid-cell-inner grid-col-name']")
参考文献
您可以在以下位置找到一些相关的详细讨论:
How to locate an element with multiple classnames using Selenium and Python【讨论】:
以上是关于Selenium python find_element_by_class_name() 从 v 2.2 到 2.21 停止工作——不能使用“复合类名”的主要内容,如果未能解决你的问题,请参考以下文章