AppCrawler自動化遍歷使用詳解(版本2.1.0 )(轉)
阿新 • • 發佈:2018-12-13
AppCrawle是自動遍歷的app爬蟲工具,最大的特點是靈活性,實現:對整個APP的所有可點選元素進行遍歷點選。
優點:
1.支援android和iOS, 支援真機和模擬器
2.可通過配置來設定遍歷的規則(比如設定黑名單和白名單,提高遍歷的覆蓋率)
3. 其本身的遍歷深度覆蓋較全,比如它擁有APP的dom樹,根據每個activity下的可點選元素逐個點選,比monkey更具有規律性,覆蓋更全面
4.生成的報告附帶截圖,可以精確看到點選了哪個元素及結果,對crash類的問題定位清晰
缺點:
1. 只能定位一頁,對於翻頁的無法進行下滑再點選,導致下面的內容無法遍歷(需要自己設定下滑然後翻頁)
2.對於呼叫第三方應用的不太穩定,比如每次到上傳頭像處就停止遍歷
3.對於 整個layout區域是可點選,但是其中某個元素是不可點選的,沒有進行遍歷點選,比如:左上角的設定和右上角的私信都不能遍歷到
4.對於H5頁面無法進行精確的定位點選,比如它的整個佈局layout是 一個大模組,不能進行點選 (機會頁,融資速遞,新品優選)
一.環境搭建:(前提是當然得有Java環境)
1.appcrawler的最新jar包(最新的功能多,相容性比較高),我用的是 appcrawler-2.1.0.jar ,
下載地址如下:
百度網盤:
https://pan.baidu.com/s/1bpmR3eJ
2. appium ,用來開啟session服務並定位元素的,也可以使用 appium GUI(桌面版),但是我使用跑了一半就崩潰了,記憶體不足,所以推薦使用命令列版本的
下載方式:
(1)在命令列下執行npm --registry http://registry.cnpmjs.org install -g appium (推薦這種,npm的國內映象)
(2)檢查appium所需的環境是否OK(這步很重要):進入Cmd命令列,輸入appium-doctor 顯示正常則成功
3.Android SDK,主要是為了使用tools資料夾下的 uiautomatorviewer.bat 來定位元素,獲取元素的xpath,用於準備工作前期。
二.執行步驟:
1.手機安裝好最新的安裝包,不需要登陸(避免不能遍歷登陸前的頁面內容,且登入後再進行遍歷會出現activity不一致的報錯,即和launchActivity不一致)
2.開啟appium服務
在命令列中輸入: appium ,提示: 則開啟成功
3.在放 appcrawler-2.1.0.jar 的資料夾下執行以下命令:
Java -jar appcrawler-2.1.0.jar -a jingdata.apk -c config.yml --output wyy/
即可自動啟動APP,並自動遍歷點選元素
因為遍歷的深度比較大,在覆蓋比較全面的條件下,我這邊測試會有496條case左右,基本要跑1個小時左右。
最後自動生成的報告如下:
三. 如何寫配置檔案 config.yml (這才是執行的核心所在)
引數說明:
Java -jar appcrawler-2.1.0.jar 用來啟動appcrawler
-a 後面跟安裝包的名字 (用於自己手機沒有安裝包的時候的使用)
-c 後面跟自定義的配置檔案的路徑和名字
-output 後面跟輸出的報告所在的資料夾,如果沒有寫,則會自動生成一個以時間為資料夾名字的報告檔案
其實這裡的重點就是如何來寫配置檔案:
配置檔案基本都是以key-value格式,所以可以用文字編輯器,然後改名為 .yml或者.json檔案即可。
先上一下我的配置檔案 config.yml:
--- logLevel: "TRACE" reportTitle: "Jingdata" #指生成的HTML(index.html)報告頭部顯示的標題資訊 saveScreen: true screenshotTimeout: 20 currentDriver: "android" showCancel: true tagLimitMax: 5 tagLimit: - xpath: //*[../*[@selected='true']] count: 12 maxTime: 10800 resultDir: "" #結果資料夾名,給定後,將不動態命名 capability: newCommandTimeout: 120 launchTimeout: 120000 platformVersion: "" platformName: "Android" autoWebview: "false" autoLaunch: "true" noReset: "true" androidInstallTimeout: 180000 androidCapability: deviceName: "" appPackage: "com.android36kr.investment" appActivity: "" #寫不寫無所謂,因為APP會自動判別當前的activity是否正確,是不是launchActivity,如果不是則會報錯 dontStopAppOnReset: true app: "" appium: "http://127.0.0.1:4723/wd/hub" # automationName: uiautomator2 automationName: uiautomator2 reuse: 3 headFirst: true enterWebView: true urlBlackList: - //*[contains(@resource-id, "tv_setting_logout") and @clickable='true'] #登出 - //*[contains(@resource-id, "toolbar_close") and @clickable='true'] # 關閉按鈕,否則會陷入死迴圈一直遍歷同一個頁面 - //*[contains(@resource-id, "login_36kr_forgot_pass") and @clickable='true'] # 忘記密碼,避免登陸時按照遍歷順序影響登陸 - //*[contains(@resource-id, "mine_info_icon") and @clickable='true] # 我的資料 頭像部分設定不可點選(每次一執行到這裡就結束了) - //*[contains(@resource-id, "tv_name") and @clickable='true] #頭部卡片 姓名 - //*[contains(@resource-id, "tv_company_name") and @clickable='true] # 頭部卡片 公司和職位 - //*[contains(@resource-id, "company_avatar") and @clickable='true] # 頭部 禁止進入我的資料頁面 - //*[contains(@resource-id, "chat_invest_card_rl") and @clickable='true] # 聊天頁的專案頭部,避免又進入詳情頁,跳出了迴圈 - //*[contains(@resource-id, "chat_send_contact_ll") and @clickable='true] #聊天詳情頁,交換名片,避免遍歷線上包時與線上使用者互動 - //*[contains(@resource-id, "ll_header") and @clickable='true] # 我的資料頭像部分的整個頭部區域,因為一點選頭像後喚起照相就不運行了 urlWhiteList: - //*[contains(@resource-id, "login_36kr_ll") and @clickable='true'] #必須遍歷賬號密碼登入的按鈕(以此方式才能登入成功) - //*[contains(@resource-id, "fl_msg") and @clickable='true'] #右上角的私信按鈕 - //*[contains(@resource-id, "iv_setting") and @clickable='true'] # 左上角的設定按鈕 backButton: - //*[contains(@resource-id, "toolbar_back") and @clickable='true'] triggerActions: # 主要解決登入的問題,當遇到登入輸入框時,輸入內容,比testcase更好用 - action: "1771019****" xpath: "//*[@resource-id='com.android36kr.investment:id/login_36kr_phone_edit']" times: 1 - action: "123456" xpath: "//*[@resource-id='com.android36kr.investment:id/login_36kr_pass_code']" times: 1 - action: "click" xpath: "//*[@resource-id='com.android36kr.investment:id/login_36kr_go_btn']" times: 1 - action: "swipe("down")" xpath: "//*[@resource-id='com.android36kr.investment:id/share']" times: 1 startupActions: - swipe("left") - println(driver) testcase: name: swipeTest steps: - when: xpath: //*[contains(@resource-id, 'share')] action: driver.swipe(0.5,0.8,0.5,0.2) then: []還有一些其他的引數說明如下:
1、java -jar appcrawler-2.1.0.jar --capability appPackage=xxxxxx,appActivity=xxxxxx 2、appium --session-override:4:10,配置檔案說明:11:00(看視訊主要地方) 3、配置檔案使用:true和false是開啟和關閉的意思 logLevel:日誌級別 saveScreen:是否截圖 reportTitle:報告名字 screenshotTimeout:螢幕超時時間 currentDriver:當前裝置(Android/iOS) resultDir:結果資料夾名,給定後,將不動態命名 tagLimitMax:ios的元素tag控制 tagLimit:給tag maxTime:最大執行時間 showCancel:應該是控制是否展示註釋 capability:用於配置appium androidCapability:Android專屬配置,最後會和capability合併 iosCapability:iOS專屬配置 urlWhiteList/blackList:白名單/黑名單 xpathAttributes:用來設定可以用那些種類型去定位控制元件 defineUrl:用來確定url的元素定位xpath 他的text會被取出當作url因素(沒理解) baseUrl:設定一個起始url和maxDepth, 用來在遍歷時候指定初始狀態和遍歷深度 maxDepth:預設的最大深度10, 結合baseUrl可很好的控制遍歷的範圍 appWhiteList:app白名單,如果跳轉到其他app,需要設定規則,是否允許停留在次app中 headFirst:是否是前向遍歷或者後向遍歷 enterWebView:是否遍歷WebView控制元件 urlBlackList:url黑名單.用於排除某些頁面 urlWhiteList:url白名單, 第一次進入了白名單的範圍, 就始終在白名單中. 不然就算不在白名單中也得遍歷. 上層是白名單, 當前不是白名單才需要返回 defaultBackAction:預設的返回動作(沒看到例子,貌似不特指的話,是click) backButton:給一些返回控制元件,用於返回動作使用 firstList:優先遍歷元素 selectedList:預設遍歷列表,如果不是指定的型別,而是確定控制元件,會分別點選控制元件 lastList:最後遍歷的元素 blackList:排除某些控制元件 triggerActions:制定規則(action、xpath、times) autoCrawl:自動抓取,看原始碼指定true後執行crawl(conf.maxDepth)命令 (crawl——清空堆疊 開始重新計數)應該是appcrawler的主要方法 asserts:斷言,用於是否失敗的判斷 testcase:測試用例,看appcrawler日誌,每次都是首先執行用例才會往下執行 beforeElementAction:貌似沒什麼人用,字面意思在元素動作之前 afterElementAction:與beforeElementAction的待遇差不多 afterUrlFinished:也是很冷門的待遇 monkeyEvents:monkey的點選數 monkeyRunTimeSeconds:monkey執行時間 given是條件 或輸入 when是觸發條件和動作 then是斷言 4、一次ctrl+c生成報告,兩次ctrl+c是強行退出 5、終端輸入Scala進入Scala直譯器,輸入:q或:quit退出直譯器 6、遍歷的深度應該怎麼設定好,總是跳到其它頁面,就回不到當前頁面繼續遍歷了,看文件 通過黑白名單 7、設定一個起始url和maxDepth, 用來在遍歷時候指定初始狀態和遍歷深度
四. 遇到的問題有哪些?如何解決
1.登入: 因為APP的登入頁面是使用者名稱+驗證碼,由於該頁面按鈕眾多且有驗證圖示,需要滑動解鎖很複雜,所以選用了賬號密碼登入的方式 (1)設定 賬號密碼登入 按鈕為白名單,即必須點選,此時一定會編輯進入賬戶名密碼登入頁面,配置如下: urlWhiteList: - //*[contains(@resource-id, "login_36kr_ll") and @clickable='true'] #必須遍歷賬號密碼登入的按鈕 (2)設定賬號密碼登入中,使用者名稱和密碼元素的觸發器,當定位到這兩個元素時,輸入使用者名稱和密碼,配置如下: triggerActions: # 主要解決登入的問題,當遇到登入輸入框時,輸入內容,比testcase更好用 - action: "177*******" xpath: "//*[@resource-id='com.android36kr.investment:id/login_36kr_phone_edit']" times: 1 - action: "123456" xpath: "//*[@resource-id='com.android36kr.investment:id/login_36kr_pass_code']" times: 1 (3)設定賬號密碼登入中,輸入使用者名稱和密碼後,按照遍歷順序,接下來有一個忘記密碼的點選事件開啟了新頁面,為了避免登陸的多餘操作,將 忘記密碼 這個元素設定為黑名單,不進行遍歷,配置如下: urlBlackList: - //*[contains(@resource-id, "login_36kr_forgot_pass") and @clickable='true'] # 忘記密碼,避免登陸時按照遍歷順序影響登陸 2. 聊天詳情頁 因為是線上包,為了避免點選交換名片,直接傳送聯絡方式給線上使用者,所以 將 交換名片的按鈕設定 為 黑名單 3.聊天詳情頁 聊天詳情頁的專案卡片點選後重新進入到專案頁面,導致重複遍歷,所以將專案卡片的可點選元素設定為 黑名單 4.頭像部分 點選頭像會調起相機,導致執行到此處就 shutdown ,所以設定所有可點選的頭像部分都為 黑名單,執行就正常了。 yeah~ 搞定,over~~ 開心 O(∩_∩)O~~