Css deep
css 权重
从 0 开始,一个行内样式+1000,一个id+100,一个属性选择器/class 或者伪类(:hover)+10,一个元素名,或者伪元素(::after)+1
1 |
|
最终的权重值是 0122 (0,1,2,2);#content 是一个 id 选择器加了 100,.data 是一个 class 类选择器加了 10,:hover 伪类选择器加了 10, body 和 img 是元素加了 1 。
☝️**对于各种框架,组件库的样式覆盖本质都是对,css 权重的提升**
Css 与 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
一些不足
- 不能根据子元素定位父元素
- 不能根据次序范围定位子元素
- 不能选择某节点前面的兄弟节点
其代码较为简洁,但是仍存在一些不足,在实际应用中还需要了解 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 协议 ,转载请注明出处!