CSS 选择器常用语法
在selenium元素定位中的应用

概述

在之前的文章介绍过xpath的定位,可对比参考细说xpath

认识CSS选择器

在 CSS 中,选择器是一种模式,用于选择需要添加样式的元素,详情可参看CSS 选择器参考手册

  • 在selenium中常用如下
选择器 例子 例子描述
.class .intro 选择 class="intro" 的所有元素。
#id #firstname 选择 id="firstname" 的所有元素。
* * 选择所有元素。
element p 选择所有 <p> 元素。
element,element div,p 多元素选择器,选择所有 <div> 元素和所有 <p> 元素。
element element div p 后代选择器,选择 <div> 元素内部的所有 <p> 元素。
element>element div>p 子元素选择器,选择父元素为 <div> 元素的所有 <p> 元素。
element+element div+p 毗邻元素选择器,选择紧接在 <div> 元素之后的所有 <p> 元素。
element1~element2 p~ul 同级元素选择器,选择前面有 <p> 元素的每个 <ul> 元素。
[attribute] [target] 选择带有 target 属性所有元素。
[attribute=value] [target=_blank] 选择 target="_blank" 的所有元素。
[attribute1=value1][attribute2=value2] [target=_blank] [type=text] 选择 target="_blank" 且(and) type="text"的所有元素。 (同时匹配两个属性,无需and关键字)
[attribute~=value] [title~=flower] 选择 title 属性包含单词 "flower" 的所有元素。
[attribute|=value] [lang|=en] 选择 lang 属性值以 "en" 开头的所有元素。
[attribute^=value] a[src^="https"] 选择其 src 属性值以 "https" 开头的每个 <a> 元素。
[attribute$=value] a[src$=".pdf"] 选择其 src 属性以 ".pdf" 结尾的所有 <a> 元素。
[attribute*=value] a[src*="abc"] 选择其 src 属性中包含 "abc" 子串的每个 <a> 元素。
:first-child p:first-child 选择属于父元素的第一个子元素的每个 <p> 元素。
:first-of-type p:first-of-type 选择属于其父元素的首个 <p> 元素的每个 <p> 元素。
:last-of-type p:last-of-type 选择属于其父元素的最后 <p> 元素的每个 <p> 元素。
:only-of-type p:only-of-type 选择属于其父元素唯一的 <p> 元素的每个 <p> 元素。
:only-child p:only-child 选择属于其父元素的唯一子元素的每个 <p> 元素。
:nth-child(n) p:nth-child(2) 选择属于其父元素的第二个子元素的每个 <p> 元素。
:nth-last-child(n) p:nth-last-child(2) 同上,从最后一个子元素开始计数。
:nth-of-type(n) p:nth-of-type(2) 选择属于其父元素第二个 <p> 元素的每个 <p> 元素。
:nth-last-of-type(n) p:nth-last-of-type(2) 同上,但是从最后一个子元素开始计数。
:last-child p:last-child 选择属于其父元素最后一个子元素每个 <p> 元素。

验证方式

  • 在chrome开发者工具(F12) - console中输入$("css selector expr")

利用chrome开发者工具,在elements中右键copy seletor方式得到的css选择器表达式不建议使用,仅作参考

元素定位方式选择优先级

selenium基础及应用中介绍了selenium定位元素的几种方式:id,name,class_name,tag_name,link_text,xpath,css_selector等

一般情况,如果元素不能直接通过id,name,class_name,tag_name,link_text定位,我们就会采取xpath,css_selector来定位元素,这样几乎能解决所有元素的定位。但css selector和xpath之间建议优先选择前者:

  • css selector语言更简介
  • css selector定位更快,更稳定
  • css通过匹配模式定位,xpath通过遍历来定位
  • 不同的浏览器 XPath 引擎不同甚至没有自己的 Xpath 引擎,这就导致了 XPath 定位速度较慢,所以Selenium 官方也是推荐使用 css 定位
  • Xpath可以通过文本来定位,而css selector不能
  • Xpath可以通过子节点来定位父节点,css selector是前向的,不能利用子节点定位父节点。

参看Why is CSS Selector faster than XPath?

在selenium中元素定位的应用

在selenium web自动化测试中,有如下几种方式来使用css选择器来定位元素:

  • driver.find_element(By.CSS_SELECTOR, 'css selector expr')
  • driver.find_elements(By.CSS_SELECTOR, 'css selector expr')
  • driver.find_element_by_css_selector('css selector expr')
  • driver.find_elements_by_css_selector('css selector expr')
    因此想定位元素,关键在于css selector表达式

定位 class 含有空格的复合类

如定位<div class="page-title filename">12345 </div>,需要在每个class值前面加 .
即使用driver.find_elements_by_css_selector('.page-title.filename')

接下来以hao123为例,讲解css selector在元素定位中的应用

# 打开hao123首页,点击hao123推荐 - 跳转新的选项卡 - 切换选项卡 - 搜索monkeyjerry  - 切换回去 - 点击实时热点第二条
import time
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException, TimeoutException
from selenium.webdriver import ChromeOptions
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# options = ChromeOptions()
# options.add_argument('--headless')
# driver = webdriver.Chrome(options=options)
driver = webdriver.Chrome()
driver.implicitly_wait(10)
url = "http://hao123.com"
wait = WebDriverWait(driver, 10)

try:
    driver.get(url)
    wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "#indexLogo > a > img")))
except TimeoutException:
    print('loading page timeout~~~')

driver.find_element_by_css_selector("[monkey=mingzhan-zfsitebar]>a:first-child").click()
if len(driver.window_handles) > 1:
    driver.switch_to.window(driver.window_handles[1])
try:
    driver.find_element_by_css_selector("[data-hook=search-input][type=text]").send_keys("mokeyjerry")
    driver.find_element_by_css_selector("button").click()
    # print(driver.window_handles)
    driver.switch_to.window(driver.window_handles[1])
    driver.find_element(By.CSS_SELECTOR, ".hotsearch-box-list>li:nth-child(2)").click()
    time.sleep(3)
except NoSuchElementException:
    print("no such element")
except:
    print("other errors")
finally:
    driver.quit()

所有css选择器定位方式不一一举例,请结合实际项目运用