文章目录
写在前面
写爬虫时候经常遇到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:: |