背景:
遇到一个项目,使用的是钉钉扫码登录,一时间不知道该怎么下手了,还是先F12抓包看下都有什么数据传输吧。
分析:
先熟悉下钉钉扫码登录的逻辑,参考官文:https://open-doc.dingtalk.com/microapp/serverapi2/kymkv6
正常操作,步骤
1、打开扫码登录页面
2、打开手机钉钉扫描后,手机钉钉显示这个授权页面,点击登录按钮,二维码页面就会跳转至系统内部登录成功。
F12分析下网络数据传输
1、在扫码登录页面,刷新页面(必须要刷新,否则不会调用default_yto接口)会生成一个新的二维码,同时查看网络,发现http://*.*.*/public/api/authenticate/ddtalk/default_yto接口返回中有gotoUrl,访问这个链接
2、访问后会显示登录钉钉页面,同时注意到页面上方写着统一登录平台(测试环境),说明此登录就是为了目标网站登录做授权:
3、输入账号密码后,成功进入系统,搞定!开心
操作:
上面已经分析出来了,步骤如下:
1、调用default_yto接口,提取到gotoUr链接
2、访问该链接,使用selenium输入账户和密码登录系统
实现代码如下:
文字版:
*** Settings ***
Library RequestsLibrary
Library Selenium2Library
*** Keywords ***
登录
${content-type} Create Dictionary Content-Type application/json
Create Session api url=http://*.*.*.* headers=${content-type}
${ret} Get Request api /public/api/authenticate/ddtalk/default_yto
log ${ret.content}
${result_json} To Json ${ret.content}
${gotoUrl} Set Variable ${result_json['data']['gotoUrl']}
log ${gotoUrl}
Open Browser ${gotoUrl} gc
Click Element //a[contains(text(),'登录钉钉账号')]
Click Element //div[contains(text(),'请输入手机号码')] #必须点击div,再input,否则不能定位元素
Input Text //*[@id="mobile"] *******
Click Element //div[contains(text(),'请输入密码')]
Input Password //input[@id="pwd"] **********
Click Element //a[@id="loginBtn"]
遇到的问题:
1、定位“登录钉钉账号”元素
定位登录钉钉账号按钮时,总是提示找不到元素,
绝对路径:/html/body/section[2]/a[1]
相对路径://*[@href='https://login.dingtalk.com/login/index.htm?goto=https%3A%2F%2Foapi.dingtalk.com%2Fconnect%2Foauth2%2Fsns_authorize%3Fappid%3Ddingoap0sqtaucbscestgg%26response_type%3Dcode%26scope%3Dsnsapi_login%26state%3D47414c2cd98b8b106b03da509cf1361bsrWbAM4S19o%26redirect_uri%3Dhttp%3A%2F%2F61.152.207.98%2Fpublic%2Fapi%2Fauthenticate%2Fddtalk%2Fcallback']
等等各种方法都找不到元素,还联系了钉钉客服,问是不是做了反爬,反爬也是针对调用接口说的,我这只是页面点击元素应该不至于吧。
最后使用//a[contains(text(),'登录钉钉账号')],成功定位到元素。
2、定位输入账号密码输入框元素
元素定位时,发现聚焦输入框时对应的html是div标签,奇怪,不应该是input框吗?
既然人家定位到div标签那就写div标签的xpath吧,但是无论如何都不能输入,
在输入框中输入数据后,定位又指向了input标签,怀疑是需要先点击一下div元素,在input输入,实施后果然如我猜想,好了,搞定了,休息下吧。
总结:
1、定位元素时使用xpath的话,//后最好加上需要定位的标签,如定位登录钉钉账号元素//a[contains(text(),'登录钉钉账号')],不要写成//*[contains(text(),'登录钉钉账号')],这样有可能找不到元素,而且效率低。
2、定位元素暂时找不到,不要心急,各种换,总有能定位到的。