
本文详解为何 find_element(By.CLASS_NAME, "a b") 会失败,并提供使用 CSS 选择器精准定位多类名元素的完整解决方案,包含显式等待、语法说明与最佳实践。
本文详解为何 `find_element(by.class_name, "a b")` 会失败,并提供使用 css 选择器精准定位多类名元素的完整解决方案,包含显式等待、语法说明与最佳实践。
在 Selenium 中,By.CLASS_NAME 仅支持单个类名(class) 的精确匹配,且不接受空格分隔的多个类名(如 "css-v84xw-NakedButton eml2css7")。当你传入含空格的字符串时,Selenium 会将其整体视为一个类名进行查找,而 HTML 中并不存在名为 css-v84xw-NakedButton eml2css7 的单一 class,因此触发 NoSuchElementException。
正确的做法是改用 By.CSS_SELECTOR:
- 若需同时匹配多个 class(即元素同时拥有 css-v84xw-NakedButton 和 eml2css7),应写作 .css-v84xw-NakedButton.eml2css7(无空格,表示“同时具备”);
- 若误写为 .css-v84xw-NakedButton .eml2css7(带空格),则表示“后代选择器”,即查找 eml2css7 类在 css-v84xw-NakedButton 类内部的子元素——这与目标
此外,原始代码中还存在几个关键问题,需一并修正:
- 未使用显式等待:页面动态加载内容(如酒店房型区域)需等待目标按钮可点击,而非依赖 implicitly_wait 或立即操作;
- 重复导入:webdriver 被导入两次,属冗余;
- find_element('class name', ...) 写法已弃用:新版本 Selenium(4.0+)强制要求使用 By 枚举常量,字符串形式(如 'class name')不再支持;
- 缺少异常处理与资源清理:未关闭浏览器,长期运行易导致资源泄漏。
✅ 推荐修复后的完整代码如下:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
def rooms():
driver = webdriver.Chrome()
try:
driver.get("https://www.qantas.com/hotels/properties/18482?adults=2&checkIn=2024-04-16&checkOut=2024-04-17&children=0&infants=0#view-rooms")
# 显式等待:等待按钮出现且可点击(推荐)
wait = WebDriverWait(driver, 15)
expand_button = wait.until(
EC.element_to_be_clickable((By.CSS_SELECTOR, ".css-v84xw-NakedButton.eml2css7"))
)
expand_button.click()
print("✅ 房型详情已成功展开")
except Exception as e:
print(f"❌ 操作失败:{e}")
finally:
driver.quit() # 确保浏览器关闭
if __name__ == "__main__":
rooms()
? 关键要点总结:
- ✅ By.CLASS_NAME 仅用于单类名,如 By.CLASS_NAME, "eml2css7"(但本例中单独使用可能不唯一,不推荐);
- ✅ 多类名必须用 By.CSS_SELECTOR,且类名间无空格(.a.b 表示“同时具有 a 和 b”);
- ✅ 始终优先使用 WebDriverWait + expected_conditions,避免因渲染延迟导致的定位失败;
- ✅ 避免 driver.find_element('class name', ...) 等旧式字符串调用,统一使用 By.* 常量;
- ✅ 生产环境务必包裹 try/finally 或使用上下文管理器确保 driver.quit() 执行。
掌握这一原则,不仅能解决当前按钮点击问题,更能系统规避绝大多数因定位策略不当引发的 NoSuchElementException。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











