影刀RPA新手教程:CSS选择器实战手册——八种语法与XPath的选型指南
CSS选择器是元素定位的另一大杀器。上一篇讲了XPath,这篇专攻CSS选择器,并且给你XPath vs CSS的选型指南。
我第一次用CSS选择器的时候,觉得语法比XPath简单,后来发现功能也弱一些。但某些场景下,CSS选择器比XPath好用。
这篇不讲废话,直接给用法、给代码、给选型建议。
一、CSS选择器八种语法详解
1.1 语法一:标签选择器(最基础)
语法格式:
标签名适用场景:页面上只有这一个标签,或者你想选中所有这个标签。
真实项目代码(选中所有input标签):
input在影刀中的使用:
- 用【获取相似元素列表(web)】指令
- 定位方式选择"CSS选择器"
- CSS选择器填写
input - 元素操作选择"获取元素对象"
为什么用这个写法:比如你要给页面上所有输入框批量填入数据,用标签选择器一键选中所有input。
踩坑:如果页面上有很多input,你可能只想选中某个特定的input。
解决方案:用更精确的选择器(比如ID选择器、类选择器)。
1.2 语法二:类选择器(最常用)
语法格式:
.类名适用场景:元素的class属性稳定,且你想要选中所有具有这个类名的元素。
真实项目代码(选中所有class包含"product-title"的元素):
.product-title为什么用这个写法:电商商品列表,每个商品的标题都有class="product-title",用类选择器可以一键选中所有商品标题。
在影刀中的使用:
- 用【获取相似元素列表(web)】指令
- 定位方式选择"CSS选择器"
- CSS选择器填写
.product-title - 元素操作选择"获取元素文本内容"
- 保存到变量
商品标题列表
踩坑点1:class包含多个值。
比如class="product-title hot",用.product-title是可以匹配到的,因为CSS选择器的类选择器是"包含"逻辑,不是"等于"逻辑。
这和XPath的contains函数类似。
踩坑点2:类名中有空格。
比如class="product title"(两个不同的类名),用.product.title可以同时匹配product和title两个类。
如果想匹配同时包含product和title的元素,用.product.title(中间没有空格)。
如果想匹配class是"product title"的元素(包含两个词),用.product.title也可以。
1.3 语法三:ID选择器(最精确)
语法格式:
#id值适用场景:元素有id属性,且id是唯一的(HTML规范规定id必须唯一)。
真实项目代码(选中id是"submit-btn"的元素):
#submit-btn为什么用这个写法:id在页面上是唯一的,用ID选择器定位,准确率100%。
踩坑:如果页面上有多个相同的id(虽然不符合HTML规范,但有些前端会写错),CSS选择器只会选中第一个。
解决方案:用属性选择器(见语法四)。
1.4 语法四:属性选择器(最灵活)
属性选择器有五种写法:
写法一:精确匹配
[属性="属性值"]示例:
input[type="text"]匹配所有type是"text"的input标签。
写法二:开头匹配
[属性^="开头部分"]示例:
div[id^="product-"]匹配所有id以"product-"开头的div。
这和XPath的starts-with函数类似。
写法三:结尾匹配
[属性$="结尾部分"]示例:
img[src$=".jpg"]匹配所有src以".jpg"结尾的img标签。
这和XPath的ends-with函数类似(但XPath 1.0不支持ends-with)。
写法四:包含匹配
[属性*="部分值"]示例:
div[class*="product"]匹配所有class包含"product"的div。
这和XPath的contains函数类似。
写法五:单词匹配
[属性~="单词"]示例:
div[class~="product"]匹配所有class属性中包含"product"这个单词的div(必须是独立的单词,不能是单词的一部分)。
区别:
[class*="product"]可以匹配class="product-title"(product是product-title的一部分)[class~="product"]不能匹配class="product-title",只能匹配class="product title"(product是一个独立的单词)
1.5 语法五:后代选择器(最常用之一)
语法格式:
祖先选择器 后代选择器注意:中间有空格,表示"在祖先元素里面找后代元素"。
真实项目代码(选中product-list里面的所有product-title):
.product-list .product-title解释:
.product-list:选中class是"product-list"的元素- 空格:表示后代(不一定是直接子元素,可以是任意层级的后代)
.product-title:选中在.product-list里面的class是"product-title"的元素
为什么用这个写法:电商商品列表,商品标题都在商品列表容器里面。用后代选择器可以限定范围,避免选中页面其他地方的同名元素。
踩坑:空格表示任意层级的后代。
比如.product-list .product-title可以匹配:
<divclass="product-list"><div><spanclass="product-title">商品标题</span></div></div>即使.product-title不是.product-list的直接子元素,也能匹配到。
如果想只匹配直接子元素,用子代选择器(见语法六)。
1.6 语法六:子代选择器(比后代选择器更严格)
语法格式:
父选择器 > 子选择器注意:中间是>,表示"只找直接子元素"。
真实项目代码(选中product-list的直接子元素product-item):
.product-list > .product-item解释:
.product-list:选中class是"product-list"的元素>:表示直接子元素(必须是父子关系,中间不能有其他元素).product-item:选中.product-list的直接子元素中class是"product-item"的元素
为什么用这个写法:如果.product-list里面还嵌套了其他.product-item(比如子分类),用后代选择器会匹配到所有层级的.product-item,用子代选择器只匹配第一层。
踩坑:>前后可以有空格,也可以没有空格。
以下三种写法等价:
.product-list > .product-item .product-list> .product-item .product-list >.product-item1.7 语法七:相邻兄弟选择器(适合找相邻元素)
语法格式:
前一个选择器 + 后一个选择器注意:中间是+,表示"找紧挨着的前一个元素的后一个元素"。
真实项目代码(选中在"点赞"后面的span):
span.like + span解释:
span.like:选中class是"like"的span+:表示相邻兄弟(必须是紧挨着的)span:选中后面的span
为什么用这个写法:小红书笔记详情页,点赞数在"点赞"这个span的后面,且紧挨着。用相邻兄弟选择器可以精确定位。
踩坑:+只匹配紧挨着的元素。
如果中间隔了一个元素,就匹配不到了。
解决方案:用~(通用兄弟选择器)。
语法:
前一个选择器 ~ 后一个选择器示例:
span.like ~ span匹配所有在span.like后面的span(不一定紧挨着)。
1.8 语法八:伪类选择器(最强大)
伪类选择器有很多种,这里讲最常用的几种:
伪类一::nth-child(n)(选中第n个子元素)
语法格式:
选择器:nth-child(n)真实项目代码(选中product-list的第二个子元素):
.product-list > .product-item:nth-child(2)解释:
.product-list > .product-item:选中.product-list的直接子元素中class是"product-item"的元素:nth-child(2):从中选出第二个
为什么用这个写法:比如你要采集商品列表的前三个商品,用:nth-child(1)、:nth-child(2)、:nth-child(3)分别选中。
踩坑:nth-child(n)的n从1开始,不是从0开始。
这和XPath的child::下标一样。
伪类二::first-child(选中第一个子元素)
语法格式:
选择器:first-child示例:
.product-list > .product-item:first-child等价于:nth-child(1)。
伪类三::last-child(选中最后一个子元素)
语法格式:
选择器:last-child示例:
.product-list > .product-item:last-child伪类四::not(选择器)(排除符合条件的元素)
语法格式:
选择器:not(排除条件)真实项目代码(选中所有product-item,但排除class包含"advertisement"的):
.product-item:not(.advertisement)为什么用这个写法:电商商品列表里可能有广告商品,用:not()可以排除广告。
二、XPath vs CSS选择器,选型指南
2.1 功能对比
| 功能 | XPath | CSS选择器 |
|---|---|---|
| 属性精确匹配 | [@id="kw"] | #kw或[id="kw"] |
| 属性模糊匹配 | contains(@class,"product") | [class*="product"] |
| 以…开头 | starts-with(@id,"product-") | [id^="product-"] |
| 以…结尾 | ends-with(@id,".jpg")(XPath 1.0不支持) | [id$=".jpg"] |
| 父元素 | //div/..或//div/parent::* | 不支持(CSS没有父元素选择器) |
| 子元素 | //div/child::span或//div/span | div > span或div span |
| 前面的兄弟 | preceding-sibling::span | 不支持(CSS只能选后面的兄弟) |
| 后面的兄弟 | following-sibling::span | span + span或span ~ span |
| 下标 | //div[1] | div:nth-child(1) |
| 逻辑运算 | and、or、not() | :not()只有排除功能 |
结论:
- XPath功能更强,尤其是父元素、前面的兄弟元素定位
- CSS选择器语法更简洁,但功能弱一些
2.2 性能对比
一般情况下,CSS选择器比XPath快。
因为:
- CSS选择器是浏览器原生支持的,查询速度快
- XPath需要浏览器额外解析,查询速度慢一些
但在影刀RPA中,这个差异可以忽略。因为RPA的瓶颈通常是网页加载速度、指令执行速度,而不是元素定位速度。
我的建议:不要为了性能选CSS,要根据功能需求选。
2.3 选型建议
优先用XPath的场景:
- 需要定位父元素(
parent::) - 需要定位前面的兄弟元素(
preceding-sibling::) - 需要使用复杂的逻辑运算(
and、or、not()) - 需要向上遍历DOM树
优先用CSS选择器的场景:
- 只需要简单的属性匹配
- 需要选中同层级后面的兄弟元素(
+或~) - 觉得XPath语法太复杂,想用更简洁的语法
- 需要排除某些元素(
:not())
我的经验:
- 新手先用元素捕获,不行再用XPath
- XPath学会了,90%的场景都能搞定
- CSS选择器可以作为补充,但不是必须
- 如果XPath和CSS都能实现,选你熟悉的那个
三、案例实战:采集拼多多商品搜索结果页
下面用一个完整案例,把CSS选择器八种语法串起来。
需求:采集拼多多商品搜索结果页的商品信息:
- 商品标题
- 商品价格
- 商品销量
- 商品评价数
实现方案:对每个数据用不同的CSS选择器语法(为了演示不同语法的应用场景)。
3.1 采集商品标题(用类选择器)
商品标题通常有稳定的class,用类选择器最合适。
CSS选择器写法:
.product-title指令配置:
用【获取相似元素列表(web)】指令
定位方式选择"CSS选择器"
CSS选择器填写
.product-title元素操作选择"获取元素文本内容"
保存到变量
商品标题列表
3.2 采集商品价格(用后代选择器)
商品价格在商品容器的里面,用后代选择器限定范围。
CSS选择器写法:
.product-item .price解释:
.product-item:商品容器- 空格:后代选择器
.price:价格元素(在商品容器里面)
指令配置:
- 用【获取相似元素列表(web)】指令
- 定位方式选择"CSS选择器"
- CSS选择器填写
.product-item .price - 元素操作选择"获取元素文本内容"
- 保存到变量
商品价格列表
3.3 采集商品销量(用属性选择器)
商品销量的class可能包含多个值,用属性选择器的包含匹配。
CSS选择器写法:
[class*="sales"]解释:
[class*="sales"]:class包含"sales"的元素
指令配置:
- 用【获取相似元素列表(web)】指令
- 定位方式选择"CSS选择器"
- CSS选择器填写
[class*="sales"] - 元素操作选择"获取元素文本内容"
- 保存到变量
商品销量列表
3.4 采集商品评价数(用伪类选择器)
商品评价数可能是某个容器的最后一个子元素,用:last-child。
CSS选择器写法:
.product-item .info:last-child解释:
.product-item .info:商品信息容器- 空格:后代选择器
:last-child:最后一个子元素
指令配置:
- 用【获取相似元素列表(web)】指令
- 定位方式选择"CSS选择器"
- CSS选择器填写
.product-item .info :last-child - 元素操作选择"获取元素文本内容"
- 保存到变量
评价数列表
3.5 数据整合
用【ForEach列表循环】指令,遍历商品标题列表,同时取出对应位置的价格、销量、评价数,写入Excel。
具体操作流程:
- 用【获取相似元素列表(web)】指令,分别获取商品标题列表、价格列表、销量列表、评价数列表
- 用【ForEach列表循环】指令,循环商品标题列表
- 在循环体内,用【获取列表项】指令,按当前循环的下标取出对应位置的价格、销量、评价数
- 用【写入Excel行】指令,将标题、价格、销量、评价数写入Excel的一行
四、常见报错及解决方案
4.1 报错:未找到元素
原因:
- CSS选择器语法写错了
- 元素还没加载出来
- 元素在iframe里面
解决方案:
- 检查CSS选择器语法,确保类名、ID名等写对
- 在【获取元素对象(web)】指令中,设置"等待元素存在(s)"为5秒或更长
- 如果元素在iframe里面,先用【切换到iframe(web)】指令切换到iframe,再定位元素
4.2 报错:匹配到多个元素
原因:CSS选择器不够精确,匹配到了多个元素。
解决方案:
- 用更精确的选择器(比如加上父元素限定)
- 用
:nth-child(n)选中特定位置的元素 - 改用【获取相似元素列表(web)】指令,获取所有匹配的元素
4.3 报错:CSS选择器在影刀中不支持
原因:某些高级CSS语法,影刀可能不支持。
解决方案:
- 用更基础的CSS语法代替
- 改用XPath选择器
五、总结
CSS选择器八种语法:
- 标签选择器:最基础,
input - 类选择器:最常用,
.product-title - ID选择器:最精确,
#submit-btn - 属性选择器:最灵活,
[type="text"]、[class*="product"] - 后代选择器:最常用之一,
.product-list .product-title - 子代选择器:更严格,
.product-list > .product-item - 相邻兄弟选择器:找相邻元素,
span.like + span - 伪类选择器:最强大,
:nth-child(n)、:not(.advertisement)
XPath vs CSS选择器:
- XPath功能更强,适合复杂场景
- CSS选择器语法更简洁,适合简单场景
- 新手建议先学XPath,覆盖90%的场景
新手最重要的是:多练。找个项目实战,把八种语法都试一遍,自然就掌握了。
更多案例在影刀RPA学习主页 home.linyan.cloud
#影刀RPA #CSS选择器 #XPath #元素定位 #新手入门
作者:林焱