背景:
遇到一個項目,使用的是釘釘掃碼登錄,一時間不知道該怎么下手了,還是先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、定位元素暫時找不到,不要心急,各種換,總有能定位到的。