tagui之select功能在Linux下无效的问题
侧边栏壁纸
博主昵称
yuc

  • 累计撰写 291 篇文章
  • 累计收到 0 条评论

tagui之select功能在Linux下无效的问题

yuc
yuc
2024-03-22 / 最后修改: 2024-03-22 03:58 / 0 评论 / 5 阅读 / 正在检测是否收录...
0x1 select功能的使用

在当前需要rpa操作的网站,有一个证件类型下拉框,源码如下: 可以看到使用了 select 元素,对应到站点的功能就是下拉框选择。于是我的代码使用了 r.select('//select[ @id="stIdcardCode" ]','居民身份证 ') 这在 windows 上运行了数十次都比较正常,但是在迁移到 Linux 上测试却发现无论如何也勾选不上,这真的是一个令人烦恼的事情。

0x2 问题排查

对比了双方系统的chrome版本,一个108一个109,基本上都是比较高比较新的版本了,问题不应该出在这里,所以我又查看了 tagui 的 src 运行日志如下:

[tagui] INPUT  - 
[980] {"id":980,"method":"Runtime.evaluate","params":{"expression":"document.evaluate('//*[@id=\"stHoldIdcardNo\"]',document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null).snapshotItem(0).focus()"}}
[tagui] OUTPUT - 
[980] {"id":980,"result":{"result":{"type":"undefined"}}}

[tagui] INPUT  - 
[981] {"id":981,"method":"Input.dispatchKeyEvent","params":{"type":"char","text":"\r"}}
[tagui] OUTPUT - 
[981] {"id":981,"result":{}}

[tagui] INPUT  - 
[982] {"id":982,"method":"Runtime.evaluate","params":{"expression":"document.evaluate('//*[@id=\"stHoldIdcardNo\"]',document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null).snapshotItem(0).focus()"}}
[tagui] OUTPUT - 
[982] {"id":982,"result":{"result":{"type":"undefined"}}}

[tagui] INPUT  - 
[983] {"id":983,"method":"Runtime.evaluate","params":{"expression":"document.evaluate('//*[@id=\"stIdcardCode\"]',document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null).snapshotLength"}}
[tagui] OUTPUT - 
[983] {"id":983,"result":{"result":{"type":"number","value":1,"description":"1"}}}

[tagui] INPUT  - 
[984] {"id":984,"method":"Runtime.evaluate","params":{"expression":"document.evaluate('//*[@id=\"stIdcardCode\"]',document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null).snapshotLength"}}
[tagui] OUTPUT - 
[984] {"id":984,"result":{"result":{"type":"number","value":1,"description":"1"}}}

[tagui] INPUT  - 
[985] {"id":985,"method":"Runtime.evaluate","params":{"expression":"var selector = '//*[@id=\"stIdcardCode\"]'; var valueToMatch = '居民身份证'; var found = false; if ((selector.indexOf('/') == 0) || (selector.indexOf('(') == 0)) var select = document.evaluate(selector,document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null).snapshotItem(0); else var select = document.querySelector(selector); if (valueToMatch == '[clear]') valueToMatch = ''; Array.prototype.forEach.call(select.children, function(opt, i) {if (!found && opt.value.indexOf(valueToMatch) !== -1) {select.selectedIndex = i; found = true;}}); var evt = document.createEvent(\"UIEvents\"); evt.initUIEvent(\"change\", true, true); select.dispatchEvent(evt);"}}
[tagui] OUTPUT - 
[985] {"id":985,"result":{"result":{"type":"boolean","value":true}}}

前面的代码都是查找元素是否存在的,最关键的是倒数第二行关于 居民身份证 操作的步骤,从最后一行的返回结果来看是正常,我尝试把这段js拿到chrome控制台手动执行,返回的确实是 True,不过页面上仍然没有勾选 --- 因为我还没有在windows下这样验证与查看tagui日志,所以这样不能证明windows下与Linux下tagui的行为或者代码是一模一样的

0x3 解决方案

tagui的select方法比较简单,代码肯定是没有错误的,windows下无问题,并且根据 Linux 下的执行日志来看,实际上元素是匹配到的,但是最后的勾选 js 可能没有效果。所以最终尝试的解决思路是,一个是看看能否尝试使用 click 来点击选择,另一个是尝试能否自己找到有效的js代码,具体操作如下:

  1. 根据如上的元素,使用 xpath 路径 click:
# 点击下拉框
r.click('//select[ @id="stIdcardCode" ]')
# 点击所需的内容 try1
r.click('//option[text()=\''+ "居民身份证 " +'\']')
# or 
# 点击所需的内容 try2
r.click('(//option)[2]')

经过测试,上面click的方案都没有成功的选择到所需的内容

  1. 使用 js 来勾选,如下代码:
# 控制台执行
$("#stIdcardCode")[0].selectedIndex = 1
# rpa 执行
r.dom('$("#stIdcardCode")[0].selectedIndex = 1')

为什么是 #stIdcardCode 呢,因为这里是 selector 用法, #表示匹配 id ,然后获取它 0 这个元素,也就是 select 之后设置它为第一个选项,如下图 说明一下这里 selectedIndex 设置为 1 并不是说序号从 1 开始,而是我们所需的值的序号是 1,设置为 0 也是可以的,这里 0 是空,也就是什么都不选择。至此这个麻烦的 select 下拉框的问题也就解决了

PS. 关于无id的元素和其他

在页面下方关于建筑用途的下拉框,此元素只有一个 name 属性,无 id 属性,那么该如何跟上面一样控制呢?

jzyt_json = {
    "": 0,
    "住宅": 1,
    "商业": 2,
    "办公": 3,
    "工业": 4,
    "仓储": 5,
    "其他": 7,
    "综合": 7
}
fw_jzyt = jzyt_json[fwxx['FWYT']]
r.dom(f'$(\'select[name="stBuildUsed"]\')[0].selectedIndex = {fw_jzyt}')

控制的代码主要是 dom 部分,主要是通过 selector 的方式来匹配 name 属性的内容即可,其他部分的代码,主要是解决不再通过中文来下拉后选择内容,而是通过序号,所以要做一个字段映射一下中文的序号

0

评论

博主关闭了当前页面的评论