Css deep

css 权重

从 0 开始,一个行内样式+1000,一个id+100,一个属性选择器/class 或者伪类(:hover)+10,一个元素名,或者伪元素(::after)+1

1
body #content .data img:hover

最终的权重值是 0122 (0,1,2,2);#content 是一个 id 选择器加了 100,.data 是一个 class 类选择器加了 10,:hover 伪类选择器加了 10, body 和 img 是元素加了 1 。

☝️**对于各种框架,组件库的样式覆盖本质都是对,css 权重的提升**

Css 与 XPath

mdn-XPath


写爬虫时候经常遇到 HTML 元素的定位问题,针对这个问题,主流的两种思路是 CSS 选择器以及 Xpath 查询语法。下面以 selenium 自动化的 CSS 选择器以及 Xpath 语法为例进行分析比较,最后不难看出虽然 CSS 选择器语法比较简洁,但是功能还是有不太完善的地方,而 Xpath 在较为复杂的语法下也为元素定位提供了更多的选择。

选择器除了可以用在 selenium 自动化上,在 Python 提供的lxml库中也可以使用 Xpath 语法。

CSS 选择器基本语法

  • id 属性选择器:#id
  • class 属性选择器:.class
  • 后代元素:``
  • 直接子元素:>
  • 根据属性选取元素:[class="s_input"]
  • 利用,进行组选择
  • 父元素第 n 个子元素::nth-child(n)
  • 父元素倒数第 n 个子元素::nth-last-child(n)
  • 父元素第 n 个某类型子元素::nth-of-type(n)
  • 父元素倒数第 n 个某类型子元素:nth-last-of-type(n)
  • 奇数元素:odd
  • 偶数元素:even
  • 兄弟元素:相邻(紧跟)关系:span + p
  • 兄弟元素:后续所有:span~p
一些不足
  1. 不能根据子元素定位父元素
  2. 不能根据次序范围定位子元素
  3. 不能选择某节点前面的兄弟节点

其代码较为简洁,但是仍存在一些不足,在实际应用中还需要了解 Xpath 的基本语法。

Xpath 查询基本语法

  • 直接子元素:/(单个/表示整个 HTML 文档的根节点)
  • 后代元素://
  • 属性选择:[@id='1']或者[@class='input']或者直接[@checkbox]
  • 所有直接子元素:使用通配符*
  • 属性包含字符串:使用函数contains(@class, ' ')
  • 属性值以某字符串开头或结尾:使用函数starts-with(@class, ' ')ends-with(@class, ' ')
  • 根据次序选择:某类型第 n 个子元素:div[n](有点类似 Python 列表索引)
  • 某类型倒数第 n 个子元素:div[last()-(n-1)]
  • 根据次序选择:第 n 个子元素:*[n](采用通配符,即不指定节点类型)
  • 次序范围:前 n 个子元素div[position()<=n]
  • 后 n 个子元素:div[position()>=last()-(n-1)]
  • 组选择:|
  • 选择父节点:/..(有点类似文件系统的上级目录)
  • 选择某节点的后续兄弟节点、前面兄弟节点:following-sibling::preceding-sibling::

二者的主要对比

相同

  • 都是进行 HTML 元素定位的选择器
  • 主流浏览器均支持这两种语法
  • 均可使用通配符*进行任意节点的选择

不同

总的来说,CSS 选择器较为简洁,但其结构不够灵活,不能够定制复杂的 HTML 元素;而 Xpath 虽然语法上某些方面有点复杂,但是其可以选取的内容更丰富,特别是对父节点的反向选择上,这是 CSS 选择器无法完成的,而且 Xpath 内置的函数又使结构更易定制。在实际使用中,可以对二者进行适当选择。

语法方面

| 比较项目 | CSS Selector | Xpath |
| ——————— | ————————————————————- | ———————————– | — |
| 直接子节点 | > | / |
| 后代子节点 | `` | // |
| 属性选择 | 特殊属性:.class
#id
;一般属性:[option=' '] | 只使用[@id='1'] |
| 组选择 | , | | |
| 属性值的首尾匹配 | ^
$ | starts-with()
ends-with() |
| 某类型第 n 个节点 | :nth-of-type(n) | [n] |
| 某类型倒数第 n 个节点 | :nth-last-of-type(n) | [last()-(n-1)] |
| 任意类型的第 n 个节点 | :nth-child(n) | *[n] |
| 某节点的后续兄弟节点 | ~ | following-sibling:: |


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!