CSS 选择器详细教程:原理、语法、方向/“轴”与实战

CSS 选择器详细教程:原理、语法、方向/"轴"与实战

面向:爬虫与自动化同学(Python 为主),从原理到实战。重点讲"方向/轴"的概念与 CSS 的能力边界。


1. CSS 选择器是什么?

CSS 选择器 是一套用来在 HTML 文档树中定位元素的规则语法。浏览器使用它来应用样式,而爬虫/自动化用它来定位元素。

优势

  • 语法简洁、易读
  • 浏览器原生支持,执行速度快
  • 适合大量"按 class/id/层级"的定位需求

2. 原理:DOM 树与匹配规则

HTML 会被解析成 DOM 树,CSS 选择器就是在树上做"匹配"。

核心思想:

  • 通过 标签、class、id、属性 等条件筛选节点
  • 通过 组合器(combinator) 表达节点之间的方向关系

3. CSS 基础语法速览

3.1 基本选择

css 复制代码
#id
.class
TagName

3.2 属性选择器

css 复制代码
[a]
[a="v"]
[a^="v"]  /* 以 v 开头 */
[a$="v"]  /* 以 v 结尾 */
[a*="v"]  /* 包含 v */

3.3 组合器(方向关系)

css 复制代码
A B    /* 后代 */
A > B  /* 子元素 */
A + B  /* 相邻兄弟 */
A ~ B  /* 后续兄弟 */

3.4 伪类与伪元素

css 复制代码
:first-child
:nth-child(2)
:nth-of-type(3)
:not(.disabled)

4. CSS 的"轴/方向"概念(重点)

XPath 有"轴(axis)"概念,比如 parent::ancestor::following-sibling::。CSS 没有"轴"这个术语,但组合器 + 伪类可以表达常见方向关系。

4.1 CSS 可表达的方向(类轴)

XPath 轴概念 CSS 对应方式 示例
子元素(child) > div > span
后代(descendant) 空格 div span
右侧兄弟(following-sibling) +~ h2 + p / h2 ~ p

4.2 CSS 不擅长/不支持的方向

  • 向上找父级/祖先 (XPath 的 parent::ancestor::
  • 向左找前置兄弟 (XPath 的 preceding-sibling::

这就是为什么复杂定位场景通常更推荐 XPath。

4.3 :has()(现代 CSS 的"反向选择")

CSS4 的 :has() 允许根据子元素反推父元素:

css 复制代码
div:has(> span.author)

注意:

  • 浏览器支持度较新;有些解析器/引擎不支持
  • 在 Selenium 中是否可用取决于浏览器对 :has() 的支持情况

5. 实战一:BeautifulSoup(bs4)里的 CSS 选择器

5.1 基本用法

python 复制代码
from bs4 import BeautifulSoup

html = """<div class='post'><h2>标题</h2></div>"""
soup = BeautifulSoup(html, "lxml")

# 返回列表
items = soup.select("div.post > h2")
# 返回单个(第一个)
item = soup.select_one("div.post > h2")

print(item.get_text())

5.2 属性与伪类

python 复制代码
# 属性选择
links = soup.select("a[href^='https']")

# nth-child
items = soup.select("ul > li:nth-child(2)")

5.3 bs4 注意点

  • select() 返回 列表
  • select_one() 返回 单个元素或 None
  • 伪类支持有限(通常可用的是 :nth-child:not 等常用伪类)

6. 实战二:Selenium 中使用 CSS 选择器

6.1 基本用法

python 复制代码
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get("https://example.com")

# 多元素
items = driver.find_elements(By.CSS_SELECTOR, "div.item")
# 单元素
item = driver.find_element(By.CSS_SELECTOR, "div.item")

注意:Selenium 正确写法是 By.CSS_SELECTOR,不是 By.CSS

6.2 在元素内继续定位

python 复制代码
card = driver.find_element(By.CSS_SELECTOR, "div.card")
name = card.find_element(By.CSS_SELECTOR, ".name")

6.3 搭配显式等待

python 复制代码
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

wait = WebDriverWait(driver, 10)
items = wait.until(
    EC.presence_of_all_elements_located((By.CSS_SELECTOR, "div.item"))
)

6.4 "方向/轴"场景示例

python 复制代码
# 找标题后面的第一个段落(相邻兄弟)
content = driver.find_element(By.CSS_SELECTOR, "h2.title + p")

# 找标题后面所有段落(后续兄弟)
contents = driver.find_elements(By.CSS_SELECTOR, "h2.title ~ p")

7. 其他常见使用场景

  1. Scrapy + CSS

    python 复制代码
    response.css("a::attr(href)").getall()
  2. Playwright

    python 复制代码
    page.locator("div.item")
  3. 浏览器控制台

    js 复制代码
    document.querySelectorAll("div.item")
  4. 前端样式规则调试(原始用途)


8. CSS 与 XPath 的取舍建议

需求 推荐
简单、稳定的 class/id 定位 CSS
需要向上找父级/祖先 XPath
需要复杂文本过滤 XPath
需要跨层级灵活定位 XPath

9. 常见坑与最佳实践

9.1 常见坑

  • #id 只能匹配一个元素(理论上),但 HTML 可能不规范
  • 位置伪类 :nth-child 是从 1 开始
  • :nth-child(n)所有子节点为基准,不是同标签

9.2 稳健性建议

  • 优先使用唯一 id / data-*
  • 避免过长层级
  • 尽量用结构关系(>+~)替代下标

10. 一页速查表

css 复制代码
/* 基本 */
#id
.class
Tag

/* 属性 */
[a]
[a="v"]
[a^="v"]
[a$="v"]
[a*="v"]

/* 方向 */
A B
A > B
A + B
A ~ B

/* 伪类 */
:first-child
:nth-child(2)
:not(.disabled)

11. 小结

  • CSS 选择器是 DOM 树上的匹配规则,语法简洁、性能好
  • "轴/方向"在 CSS 中用组合器 表达,但不支持向上
  • bs4 / Selenium / Scrapy / Playwright 都天然支持 CSS
  • 复杂定位建议结合 XPath 一起使用
相关推荐
tudficdew2 小时前
使用Flask快速搭建轻量级Web应用
jvm·数据库·python
爱学习的阿磊2 小时前
使用XGBoost赢得Kaggle比赛
jvm·数据库·python
智航GIS2 小时前
ArcGIS Python零基础脚本开发教程---1.1 Describe 函数
开发语言·python·arcgis
Dreaming_of_you2 小时前
pytorch/cv2/pil/torchvision处理图像缩小的最佳方案
人工智能·pytorch·python·opencv
Testopia2 小时前
走一遍 AI 学习之路 —— AI实例系列说明
开发语言·人工智能·python
机 _ 长2 小时前
YOLO26 改进 | 训练策略 | 知识蒸馏 (Response + Feature + Relation)
python·深度学习·yolo·目标检测·机器学习·计算机视觉
草青工作室2 小时前
java-FreeMarker3.4自定义异常处理
java·前端·python
hrrrrb3 小时前
【算法设计与分析】随机化算法
人工智能·python·算法