
影刀RPA新手教程元素定位完全指南——从元素捕获到XPath六种写法的实战选择元素定位是RPA里用得最多的技能。定位准了流程才能跑起来定位不准后面全白搭。我第一次做小红书数据采集的时候元素定位折腾了整整两天。后来才发现元素定位不是靠猜而是有方法的。这篇不讲废话直接给你能用的东西。一、元素定位的底层逻辑元素定位的本质就是两件事路径 限制条件。路径告诉影刀去哪找限制条件告诉影刀找哪个。1.1 三种定位方式影刀提供了三种定位方式元素捕获默认方式影刀自动帮你找路径和限制条件CSS选择器用CSS语法定位XPath选择器用XPath语法定位我第一次做的时候只会用元素捕获。后来发现元素捕获在某些情况下会失效才被迫学XPath和CSS。现在我的建议是新手先用元素捕获遇到坑了再用XPath或CSS。1.2 元素捕获的原理元素捕获不是玄学。它做的事情就是你点击页面上的某个元素影刀记录这个元素的路径比如 div div span影刀记录这个元素的限制条件比如 id“submit”、class“btn-primary”下次执行流程时影刀按照这个路径和限制条件去找元素。关键问题如果页面结构变了路径可能失效如果元素属性变了限制条件可能失效。这就是元素定位不稳定的根本原因。二、让元素定位稳定的三种方法元素定位不稳定流程就跑不顺。下面三种方法按优先级使用。2.1 方法一选稳定的HTML路径元素捕获时影刀会给你多个可选路径。选哪个原则选最短的、最稳定的路径。比如影刀可能给你两个路径路径Ahtml body div div div button太长容易受页面结构变化影响路径B//button[idsubmit]短且id通常稳定显然选路径B。具体操作捕获元素后双击进入元素编辑器看左侧的路径树哪些节点是稳定的比如有id、class的勾选稳定节点的属性取消勾选不稳定的属性我第一次做的时候把所有属性都勾选了。结果页面一刷新class变了元素就找不到了。教训只勾选稳定的属性不稳定的属性要么取消勾选要么用正则表达式通配。2.2 方法二勾选通用属性理解index/innerText/class各自适用场景元素编辑器里常见的属性有index元素在父节点中的位置0表示第一个-1表示倒数第一个innerText元素的文本内容class元素的CSS类名id元素的唯一标识符href链接地址a标签src资源地址img标签index适用场景元素没有id、class但位置固定比如导航栏的第三个按钮可以用index2定位踩坑index是相对于父节点的。如果父节点变了index可能错位。innerText适用场景元素的文本内容是固定的比如按钮上的提交文字踩坑如果文本会变比如评论(123)数字每次都变就不能勾选innerText。真实案例我做过一个酒店评论采集评论个数每次都变。勾选了innerText结果只能采集第一条评论后面的都失败了。解决方案取消勾选innerText换用href或其他稳定属性。class适用场景元素的class是稳定的不会随机变化比如classsubmit-btn这种通常很稳定踩坑有些网站的class是动态生成的比如classsubmit-btn_abc123每次刷新都变。这种就不能勾选class。判断方法F12打开开发者工具刷新页面几次看class是否变化。如果变了就不能勾选。2.3 方法三属性设全局变量实现动态匹配如果元素的某个属性是变化的但变化有规律可以用全局变量正则表达式实现动态匹配。真实场景百度的新闻和学术按钮文本会变。但变化规律是包含新或者学。操作步骤新建全局变量按钮名称编辑元素点击属性值后面的fx选择全局变量按钮名称匹配方式选择正则通配符设置全局变量的值为(新|学)意思是匹配包含新或学的文本流程执行逻辑获取已打开的网页对象设置全局变量按钮名称的值为新闻点击文本属性设置为变量按钮名称的元素匹配到新闻按钮设置全局变量按钮名称的值为学术点击文本属性设置为变量按钮名称的元素匹配到学术按钮另一个真实场景元素的class有时会包含active有时不包含。比如复选框勾选时class是CBX_active_18l33c8不勾选时是CBX_18l33c8。解决方案用正则表达式^((?!active).)*$意思是匹配所有不包含active的字符串。如果要同时排除多个关键字用^((?!disabled|prev|diff).)*$。三、XPath六种写法每种配真实项目代码XPath是元素定位的大杀器。学会了90%的定位问题都能解决。3.1 写法一属性选择器最常用语法//标签[属性属性值]适用场景知道元素的某个属性值且这个属性值稳定。真实项目代码百度搜索框//input[idkw]解释//从任意位置开始找input标签名[idkw]限制条件id等于kw另一个例子小红书笔记详情页的标题//div[classnote-title]踩坑如果class包含多个值比如classnote-title hot用[classnote-title]可能匹配不到。解决方案用contains函数见写法二。我的经验属性选择器最常用也最稳定。优先用id、name这些唯一属性。3.2 写法二模糊匹配contains第二常用语法//标签[contains(属性,部分值)]适用场景只知道元素属性的部分值或者属性值太长不想写全。真实项目代码小红书号//span[contains(text(),小红书号)]解释text()元素的文本内容contains(text(),小红书号)文本内容包含小红书号为什么用这个小红书号是小红书号xxxx这种格式冒号后面的数字是变化的但小红书号是固定的。用contains可以匹配到整个span然后再提取文本内容。另一个例子匹配class包含多个值的情况//div[contains(class,note-title)]这样可以匹配classnote-titleclassnote-title hotclasshot note-title踩坑contains是模糊匹配可能匹配到多个元素。解决方案加上位置限制比如(//div[contains(class,note-title)])[1]表示取第一个匹配项。3.3 写法三参照物定位preceding-sibling/following-sibling适合通过上下文定位语法//标签[属性属性值]/preceding-sibling::标签找前面的兄弟节点//标签[属性属性值]/following-sibling::标签找后面的兄弟节点适用场景要定位的元素没有明确属性但它旁边有个有明确属性的元素。真实项目代码小红书笔记的点赞数//span[text()点赞]/following-sibling::span解释//span[text()点赞]找到文本是点赞的span/following-sibling::span找它后面的兄弟span就是点赞数为什么用这个小红书笔记详情页点赞数、收藏数、评论数这三个数据结构是一样的。它们的前面都有个span文本分别是点赞、“收藏”、“评论”。通过点赞这个参照物就能定位到点赞数。另一个例子找前面的兄弟节点//span[text()收藏数100]/preceding-sibling::span这样可以找到收藏数100前面的span比如可能是收藏的图标。踩坑preceding-sibling和following-sibling只能找同级节点。如果要找父节点或子节点用parent::或child::见写法四。3.4 写法四层级定位child::适合逐层精确提取语法//父标签/child::子标签适用场景要精确控制层级关系逐层定位。真实项目代码小红书笔记的点赞数、收藏数、评论数//div[classinteract-container]/child::div[1]解释//div[classinteract-container]找到class是interact-container的div这是点赞、收藏、评论的容器/child::div[1]找它的第一个子div通常是点赞数如果要取第二个子div收藏数//div[classinteract-container]/child::div[2]第三个子div评论数//div[classinteract-container]/child::div[3]为什么用这个小红书笔记的点赞数、收藏数、评论数结构非常规律都是interact-container的子div。用child::可以精确控制取第几个。简化写法child::可以省略直接写/div[1]。所以上面的XPath可以简化为//div[classinteract-container]/div[1]踩坑如果页面结构变了比如插入了一个新的div下标可能错位。解决方案用contains或preceding-sibling/following-sibling减少对下标的依赖。3.5 写法五starts-with/ends-with适合属性值有规律的情况语法//标签[starts-with(属性,开头部分)]//标签[ends-with(属性,结尾部分)]适用场景属性值有规律比如都是以某个前缀开头或以某个后缀结尾。真实项目代码电商商品列表的商品ID//div[starts-with(id,product-)]解释找到id以product-开头的div。比如idproduct-12345、idproduct-67890都能匹配到。另一个例子匹配以.jpg结尾的图片//img[ends-with(src,.jpg)]踩坑ends-with在某些浏览器比如Chrome的XPath 1.0中不支持。解决方案用contains代替或者升级到支持XPath 2.0的浏览器。3.6 写法六组合写法实战中最灵活语法把前面的写法组合起来实现复杂定位。真实项目代码小红书笔记详情页提取发布时间//div[classnote-meta]/span[contains(text(),发布于)]/following-sibling::span[1]解释//div[classnote-meta]找到class是note-meta的div/span[contains(text(),发布于)]找它里面的span文本内容包含发布于/following-sibling::span[1]找这个span后面的第一个兄弟span就是发布时间为什么用组合写法真实项目的页面结构通常很复杂单一写法可能搞不定。组合写法可以应对各种复杂情况。另一个例子电商商品列表提取商品名称但只限前两行//div[classproduct-list]/div[position()2]/div[classproduct-name]解释position()2限制只取前两个商品这样可以实现只采集前两行数据的需求四、CSS选择器八种语法并列对比CSS选择器是另一种定位方式语法比XPath简洁但功能稍弱。4.1 语法一标签选择器语法标签名示例input匹配所有input标签。4.2 语法二类选择器语法.类名示例.submit-btn匹配所有class包含submit-btn的元素。4.3 语法三ID选择器语法#id值示例#kw匹配id是kw的元素。4.4 语法四属性选择器语法[属性属性值]示例input[typetext]匹配所有type是text的input标签。模糊匹配input[type^text]/* 以text开头 */input[type$ext]/* 以ext结尾 */input[type*ex]/* 包含ex */4.5 语法五后代选择器语法父选择器 子选择器中间有空格示例div.note-meta span匹配所有在classnote-meta的div里面的span。4.6 语法六子代选择器语法父选择器 子选择器示例div.interact-container div匹配所有classinteract-container的div的直接子div。后代选择器 vs 子代选择器后代选择器空格匹配所有层级的后代子代选择器只匹配直接子元素4.7 语法七相邻兄弟选择器语法选择器1 选择器2示例span.like-count span匹配所有在classlike-count的span后面的第一个span。4.8 语法八伪类选择器语法选择器:nth-child(n)示例div.product-list div:nth-child(1)匹配classproduct-list的div里面的第一个子div。其他常用伪类:first-child第一个子元素:last-child最后一个子元素:nth-last-child(n)倒数第n个子元素五、XPath vs CSS选择器选型指南什么时候用XPath需要模糊匹配contains、starts-with、ends-with需要通过上下文定位preceding-sibling、following-sibling需要向上查找parent::需要复杂的逻辑判断and、or、not什么时候用CSS选择器只需要简单的属性匹配追求执行性能CSS选择器通常比XPath快熟悉CSS语法觉得XPath太复杂我的建议新手先用元素捕获不行再用XPathXPath学会了大部分场景都能搞定CSS选择器可以作为补充但不是必须六、案例实战小红书笔记详情页数据采集下面用一个完整案例把前面讲的内容串起来。需求采集小红书笔记详情页的以下数据标题发布时间小红书号点赞数收藏数评论数实现方案对每个数据用不同的定位方法不是为了炫技而是为了演示不同方法的应用场景。6.1 采集标题用元素捕获标题通常有稳定的class直接用元素捕获就行。操作步骤用【打开网页】指令打开小红书笔记详情页用【获取元素对象(web)】指令通过元素捕获获取标题元素用【获取元素文本内容(web)】指令获取标题文本元素编辑器设置勾选class假设class是note-title且稳定取消勾选innerText标题可能变化6.2 采集发布时间用XPath的containsfollow-sibling发布时间的旁边通常有发布于这个文本可以用参照物定位。XPath写法//div[classnote-meta]/span[contains(text(),发布于)]/following-sibling::span[1]指令配置用【获取元素对象(web)】指令定位方式选择XPath选择器XPath填写上面的代码用【获取元素文本内容(web)】指令获取发布时间6.3 采集小红书号用XPath的contains小红书号的格式是小红书号xxxx可以用contains匹配。XPath写法//span[contains(text(),小红书号)]指令配置用【获取元素对象(web)】指令定位方式选择XPath选择器XPath填写上面的代码用【获取元素文本内容(web)】指令获取小红书号用【从文本中提取内容】指令用正则表达式小红书号(.*)提取号的部分6.4 采集点赞数用XPath的child::点赞数是interact-container的第一个子div。XPath写法//div[classinteract-container]/div[1]指令配置用【获取元素对象(web)】指令定位方式选择XPath选择器XPath填写上面的代码用【获取元素文本内容(web)】指令获取点赞数6.5 采集收藏数用XPath的child::收藏数是第二个子div。XPath写法//div[classinteract-container]/div[2]6.6 采集评论数用XPath的child::评论数是第三个子div。XPath写法//div[classinteract-container]/div[3]七、常见报错及解决方案7.1 报错未找到元素原因元素还没加载出来元素属性变了定位方式不对解决方案在【获取元素对象(web)】指令中设置等待元素存在(s)为5秒或更长用F12检查元素属性是否变化调整元素编辑器中的勾选项换用XPath或CSS选择器7.2 报错元素不可见原因元素存在但被隐藏了display:none或visibility:hidden解决方案用【执行JavaScript】指令设置display为block或直接删除display具体代码element.style.displayblock7.3 报错元素被遮挡原因元素被弹窗、广告等遮挡解决方案用【点击元素(web)】指令点击方式选择模拟人工点击或者用【悬停元素(web)】指令先悬停再点击八、总结元素定位是RPA的基础技能也是最容易踩坑的地方。核心要点元素定位 路径 限制条件让元素定位稳定的三种方法选稳定HTML路径、勾选通用属性、属性设全局变量XPath六种写法属性选择器、contains、preceding-sibling/following-sibling、child::、starts-with/ends-with、组合写法CSS选择器八种语法标签、类、ID、属性、后代、子代、相邻兄弟、伪类XPath适合复杂场景CSS适合简单场景新手最重要的是多练。找个项目实战踩几次坑自然就学会了。更多案例在影刀RPA学习主页 home.linyan.cloud#影刀RPA #元素定位 #XPath #CSS选择器 #新手入门作者林焱