news 2026/10/3 16:34:23

影刀RPA新手教程:CSS选择器实战手册——八种语法与XPath的选型指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
影刀RPA新手教程:CSS选择器实战手册——八种语法与XPath的选型指南

影刀RPA新手教程:CSS选择器实战手册——八种语法与XPath的选型指南

CSS选择器是元素定位的另一大杀器。上一篇讲了XPath,这篇专攻CSS选择器,并且给你XPath vs CSS的选型指南。

我第一次用CSS选择器的时候,觉得语法比XPath简单,后来发现功能也弱一些。但某些场景下,CSS选择器比XPath好用。

这篇不讲废话,直接给用法、给代码、给选型建议。

一、CSS选择器八种语法详解

1.1 语法一:标签选择器(最基础)

语法格式:

标签名

适用场景:页面上只有这一个标签,或者你想选中所有这个标签。

真实项目代码(选中所有input标签):

input

在影刀中的使用:

  1. 用【获取相似元素列表(web)】指令
  2. 定位方式选择"CSS选择器"
  3. CSS选择器填写input
  4. 元素操作选择"获取元素对象"

为什么用这个写法:比如你要给页面上所有输入框批量填入数据,用标签选择器一键选中所有input。

踩坑:如果页面上有很多input,你可能只想选中某个特定的input。

解决方案:用更精确的选择器(比如ID选择器、类选择器)。

1.2 语法二:类选择器(最常用)

语法格式:

.类名

适用场景:元素的class属性稳定,且你想要选中所有具有这个类名的元素。

真实项目代码(选中所有class包含"product-title"的元素):

.product-title

为什么用这个写法:电商商品列表,每个商品的标题都有class="product-title",用类选择器可以一键选中所有商品标题。

在影刀中的使用:

  1. 用【获取相似元素列表(web)】指令
  2. 定位方式选择"CSS选择器"
  3. CSS选择器填写.product-title
  4. 元素操作选择"获取元素文本内容"
  5. 保存到变量商品标题列表

踩坑点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-item

1.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 功能对比

功能XPathCSS选择器
属性精确匹配[@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/spandiv > span或div span
前面的兄弟preceding-sibling::span不支持(CSS只能选后面的兄弟)
后面的兄弟following-sibling::spanspan + span或span ~ span
下标//div[1]div:nth-child(1)
逻辑运算and、or、not():not()只有排除功能

结论:

  • XPath功能更强,尤其是父元素、前面的兄弟元素定位
  • CSS选择器语法更简洁,但功能弱一些

2.2 性能对比

一般情况下,CSS选择器比XPath快。

因为:

  1. CSS选择器是浏览器原生支持的,查询速度快
  2. XPath需要浏览器额外解析,查询速度慢一些

但在影刀RPA中,这个差异可以忽略。因为RPA的瓶颈通常是网页加载速度、指令执行速度,而不是元素定位速度。

我的建议:不要为了性能选CSS,要根据功能需求选。

2.3 选型建议

优先用XPath的场景:

  1. 需要定位父元素(parent::)
  2. 需要定位前面的兄弟元素(preceding-sibling::)
  3. 需要使用复杂的逻辑运算(and、or、not())
  4. 需要向上遍历DOM树

优先用CSS选择器的场景:

  1. 只需要简单的属性匹配
  2. 需要选中同层级后面的兄弟元素(+或~)
  3. 觉得XPath语法太复杂,想用更简洁的语法
  4. 需要排除某些元素(:not())

我的经验:

  • 新手先用元素捕获,不行再用XPath
  • XPath学会了,90%的场景都能搞定
  • CSS选择器可以作为补充,但不是必须
  • 如果XPath和CSS都能实现,选你熟悉的那个

三、案例实战:采集拼多多商品搜索结果页

下面用一个完整案例,把CSS选择器八种语法串起来。

需求:采集拼多多商品搜索结果页的商品信息:

  • 商品标题
  • 商品价格
  • 商品销量
  • 商品评价数

实现方案:对每个数据用不同的CSS选择器语法(为了演示不同语法的应用场景)。

3.1 采集商品标题(用类选择器)

商品标题通常有稳定的class,用类选择器最合适。

CSS选择器写法:

.product-title

指令配置:

  1. 用【获取相似元素列表(web)】指令

  2. 定位方式选择"CSS选择器"

  3. CSS选择器填写.product-title

  4. 元素操作选择"获取元素文本内容"

  5. 保存到变量商品标题列表

3.2 采集商品价格(用后代选择器)

商品价格在商品容器的里面,用后代选择器限定范围。

CSS选择器写法:

.product-item .price

解释:

  • .product-item:商品容器
  • 空格:后代选择器
  • .price:价格元素(在商品容器里面)

指令配置:

  1. 用【获取相似元素列表(web)】指令
  2. 定位方式选择"CSS选择器"
  3. CSS选择器填写.product-item .price
  4. 元素操作选择"获取元素文本内容"
  5. 保存到变量商品价格列表

3.3 采集商品销量(用属性选择器)

商品销量的class可能包含多个值,用属性选择器的包含匹配。

CSS选择器写法:

[class*="sales"]

解释:

  • [class*="sales"]:class包含"sales"的元素

指令配置:

  1. 用【获取相似元素列表(web)】指令
  2. 定位方式选择"CSS选择器"
  3. CSS选择器填写[class*="sales"]
  4. 元素操作选择"获取元素文本内容"
  5. 保存到变量商品销量列表

3.4 采集商品评价数(用伪类选择器)

商品评价数可能是某个容器的最后一个子元素,用:last-child。

CSS选择器写法:

.product-item .info:last-child

解释:

  • .product-item .info:商品信息容器
  • 空格:后代选择器
  • :last-child:最后一个子元素

指令配置:

  1. 用【获取相似元素列表(web)】指令
  2. 定位方式选择"CSS选择器"
  3. CSS选择器填写.product-item .info :last-child
  4. 元素操作选择"获取元素文本内容"
  5. 保存到变量评价数列表

3.5 数据整合

用【ForEach列表循环】指令,遍历商品标题列表,同时取出对应位置的价格、销量、评价数,写入Excel。

具体操作流程:

  1. 用【获取相似元素列表(web)】指令,分别获取商品标题列表、价格列表、销量列表、评价数列表
  2. 用【ForEach列表循环】指令,循环商品标题列表
  3. 在循环体内,用【获取列表项】指令,按当前循环的下标取出对应位置的价格、销量、评价数
  4. 用【写入Excel行】指令,将标题、价格、销量、评价数写入Excel的一行

四、常见报错及解决方案

4.1 报错:未找到元素

原因:

  1. CSS选择器语法写错了
  2. 元素还没加载出来
  3. 元素在iframe里面

解决方案:

  1. 检查CSS选择器语法,确保类名、ID名等写对
  2. 在【获取元素对象(web)】指令中,设置"等待元素存在(s)"为5秒或更长
  3. 如果元素在iframe里面,先用【切换到iframe(web)】指令切换到iframe,再定位元素

4.2 报错:匹配到多个元素

原因:CSS选择器不够精确,匹配到了多个元素。

解决方案:

  1. 用更精确的选择器(比如加上父元素限定)
  2. 用:nth-child(n)选中特定位置的元素
  3. 改用【获取相似元素列表(web)】指令,获取所有匹配的元素

4.3 报错:CSS选择器在影刀中不支持

原因:某些高级CSS语法,影刀可能不支持。

解决方案:

  1. 用更基础的CSS语法代替
  2. 改用XPath选择器

五、总结

CSS选择器八种语法:

  1. 标签选择器:最基础,input
  2. 类选择器:最常用,.product-title
  3. ID选择器:最精确,#submit-btn
  4. 属性选择器:最灵活,[type="text"]、[class*="product"]
  5. 后代选择器:最常用之一,.product-list .product-title
  6. 子代选择器:更严格,.product-list > .product-item
  7. 相邻兄弟选择器:找相邻元素,span.like + span
  8. 伪类选择器:最强大,:nth-child(n)、:not(.advertisement)

XPath vs CSS选择器:

  • XPath功能更强,适合复杂场景
  • CSS选择器语法更简洁,适合简单场景
  • 新手建议先学XPath,覆盖90%的场景

新手最重要的是:多练。找个项目实战,把八种语法都试一遍,自然就掌握了。

更多案例在影刀RPA学习主页 home.linyan.cloud

#影刀RPA #CSS选择器 #XPath #元素定位 #新手入门
作者:林焱

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/3 16:33:49

树莓派+Pico失语患者沟通板:按键、菜单、语音播报全解析

去年秋天&#xff0c;朋友的父亲脑梗出院后&#xff0c;人醒过来了&#xff0c;话却说不出来。医生说这叫运动性失语&#xff0c;听力和理解力大多还在&#xff0c;只是嘴和脑子的连线断了。那段时间&#xff0c;家里全靠按铃呼叫护士&#xff0c;但护士不可能时刻盯着&#xf…

作者头像 李华
网站建设 2026/10/3 16:31:28

这个bug,半年了才被我解决

我是写前端的&#xff0c;日常跟浏览器、组件、接口打交道。今天不聊技术&#xff0c;想聊个我亲身趟过的"隐性 bug"——用咱们这行能听懂的方式说。同行的你大概也有过这种时候&#xff1a;线上监控一堆&#xff0c;自己的身体却从没配过一条告警。一、cron 飘了我这…

作者头像 李华
网站建设 2026/10/3 16:28:39

接口基础知识

一、接口的概念接口使用interface关键字定义&#xff0c;它是一种行为规范 / 能力标准&#xff0c;主要用来规定 “某类事物必须具备哪些行为”。public interface 接口名 { }接口可以理解为&#xff1a;制定规则&#xff1b;定义能力&#xff1b;不关心具体实现&#xff0c;只…

作者头像 李华
网站建设 2026/10/3 16:25:54

Android内存泄漏就这样产生了:从Base URL改到TaoToken排查一次OOM

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华