今天使用影刀 RPA 元素编辑器编辑元素的时候,脑子里突然蹦出来两个问题:
如果最终要定位但是结构和内容完全一致,但是其父元素不同时,影刀 RPA 是不是会自动从父元素开始区分?
如果是从父元素开始区分,那么,哪个属性的优先级更高呢?
此时想到了官方在讲解定位动态元素的通用方案时提到,大家在手动调整元素属性的时候,这些元素属性的优先级是怎么样的呢?官方给的建议是:

那么,是不是影刀 RPA 通过默认方式进行定位的时候,也是采取的这种优先级呢?
针对以上两个问题,我们可以逐个进行验证,我们就通过去哪儿酒店点评数和问答数这个例子来验证一下。
问题1:如果最终要定位但是结构和内容完全一致,但是其父元素不同时,影刀 RPA 是不是会自动从父元素开始区分?
关于这一点,我们可以直接修改网页源码,把一家酒店(例如:北京三里屯CHAO酒店)的点评数和问答数改成一致的,这个时候再观察下影刀 RPA 的定位逻辑。
比如,原本这家酒店的点评数和问答数如下:

我们直接手动改下源码,把它们改为一样的:

注:修改的时候记得把括号也给改掉,因为它们是分别是中文括号和英文括号,别问我怎么知道的 ,都是泪 T T,感兴趣的话可以看下这篇文章:关于影刀 RPA 定位动态元素的一些思考和想法
现在,我们再捕获一下点评数这个元素,看看它的元素编辑:

结论:果然,默认状态下,影刀 RPA 如果最后一级元素的层级结构和内容完全一致,无法区分的时候,RPA 会自动从上一级的属性开始进行检查,最终它发现通过 class 属性即可区分出来,于是它就默认勾选了 class ,且条件是 class = current,这一点跟我们的预期是一样的。
问题 2:如果是从父元素开始区分,那么,哪个属性的优先级更高呢?
从上面的编辑器中勾选的属性来看,RPA 默认勾选的是 class 属性而非 index 属性,这说明它会优先考虑 class 属性。
现在,我们在把 class 属性也改为一致的,两个都改为 current,如下图:

然后,现在再来捕获一下点评数元素,看看会发生什么?

结论:果然,如果 class 属性也一致的情况下,就会通过 index 进行区分,这是因为,在网页元素有层级结构的情况下,同一层级的两个元素即便所有属性都相同,它们的位置也不可能完全相同。因此,这种情况下,我们就可以通过 index 或者 index-of-type 来进行区分。
这么看来,影刀 RPA 通过默认方式捕获元素时,勾选属性的优先级是:
innerText > id/class > index/index-of-type。
而当我们需要手动进行元素编辑时,官方推荐的做法是:
先考虑内容是否变化,如果不变,则使用 innerText。
如果内容变化,位置不变,则使用 index 或者 index-of-type。
如果内容和位置都变化,则使用 id 或 class。
从优先级上考虑,就是 innerText > index/index-of-type > id/class。
为什么跟我们实际测试的结果不一样呢?
我觉得原因可能在于:
如果从内容和位置的变化维度来考虑这件事儿,if...else if...else 这样的判断顺序确实更加符合人的理解逻辑。
代码运行过程中,index/index-of-type 相比于 id/class,在进行条件判断时运算效率更高,不过感觉这种可能比较小,毕竟如果真的从运算效率来考虑的话,官方默认应该也会用优先考虑 index,但实际情况并非如此。
不过,我个人还是觉得,从实际开发效率来考虑的话,如果通过 innerText 无法定位,那么,相比于 index/index-of-type 来讲,似乎先通过 class 属性判断更为高效一些,毕竟不用去分析层级结构来确定某个元素的位置。不过,正如官方介绍的那样,innerText 、index/index-of-type 以及 id/class 都有各自适用的场景,并不能说孰优孰劣,还是要看具体的业务场景。
最后,也可以给大家分享一下,面对这类问题我是怎么思考的?毕竟官方源码不开源,那我们就直接通过临时修改源码的方式模拟一些业务场景,从而反推出其底层逻辑。所以,如果大家有类似疑惑的时候,不妨尝试一下通过这种逆向反推的方式,看看能否验证自己的猜想。
------------------------------------------------------------------
PS:大家在学习的过程中想要一起交流,共同学习的话,可以加我微信哈:17600125520。