用途和特點
- 自動化完成一些重復性的任務胰舆,比如微信客服機器人
- 爬蟲自動化爬取信息骚露,為什么不通過網頁、HTTP爬取呢缚窿?有的系統(tǒng)產品沒有網頁端PC端只有app端
- 自動化測試棘幸,便于測試人員回歸部署驗證等測試
Appium自動化方案的特點
那么多自動化app的工具為什么選則appium?
- 開源免費
- 支持多個平臺(android倦零、IOS)
- 支持多種類型自動化:支持蘋果安卓原生界面的自動化够话,支持應用內嵌WebView的自動化支持手機瀏覽器中的web網站自動化支持flutter應用的自動化
- 支持多種編程語言
自動化原理
android版
IOS版
appium工作原理
大家看看這幅圖蓝翰, 包含了 3個主體部分 : 自動化程序、Appium Server女嘲、移動設備
自動化程序
自動化程序是由我們來開發(fā)的畜份,實現(xiàn)具體的 手機自動化 功能。
要發(fā)出具體的指令控制手機欣尼,也需要使用 客戶端庫爆雹。
和Selenium一樣,Appium 組織 也提供了多種編程語言的客戶端庫愕鼓,包括 java钙态,python,js菇晃, ruby等册倒,方便不同編程語言的開發(fā)者使用。
我們需要安裝好客戶端庫磺送,調用這些庫驻子,就可以發(fā)出自動化指令給手機。
Appium Server
Appium Server 是 Appium 組織開發(fā)的程序估灿,它負責管理手機自動化環(huán)境崇呵,并且轉發(fā) 自動化程序的控制指令 給 手機,并且轉發(fā) 手機給 自動化程序的響應消息馅袁。
手機設備
我們這里說的手機設備域慷,其實不僅僅是手機,包括所有 蘋果汗销、安卓的移動設備犹褒,比如:手機、平板弛针、智能手表等叠骑。
為了直觀方便的講解,這里我們簡稱: 手機
當然手機上也包含了 我們要自動化控制的 手機應用APP钦奋。
手機設備為什么能 接收并且處理自動化指令呢座云?
因為,Appium Server 會在手機上 安裝一個 自動化代理程序付材, 代理程序會等待自動化指令朦拖,并且執(zhí)行自動化指令
比如:要模擬用戶點擊界面按鈕,Appium 自動化系統(tǒng)的流程是這樣的:
自動化程序 調用客戶端庫相應的函數(shù)厌衔, 發(fā)送 點擊元素 的指令(封裝在HTTP消息里)給 Appium Server
Appium Server 再轉發(fā)這個指令給 手機上的自動化代理
手機上的自動化代理 接收到 指令后璧帝,調用手機平臺的自動化庫,執(zhí)行點擊操作富寿,返回點擊成功的結果給 Appium Server
Appium Server 轉發(fā)給 自動化程序
自動化程序了解到本操作成功后睬隶,繼續(xù)后面的自動化流程
其中锣夹,自動化代理控制,使用的什么庫來實現(xiàn)自動化的呢苏潜?
如果測試的是蘋果手機银萍, 用的是蘋果的 XCUITest 框架 (IOS9.3版本以后)
如果測試的是安卓手機,用的是安卓的 UIAutomator 框架 (Android4.2以后)
這些自動化框架提供了在手機設備上運行的庫恤左,可以讓程序調用這些庫贴唇,像人一樣自動化操控設備和APP,比如:點擊飞袋、滑動戳气,模擬各種按鍵消息等。
環(huán)境搭建
安裝包在為了方便我放在阿里云盤上面了是地址:https://sharelinkpre.rongdasoft.com/share-link/index.html?q=158e744d8a404000
步驟如下
- 安裝client編程庫
Python語言開發(fā)則使用pip install appium-python-client
使用java語言開發(fā)則使用:導jar包方式進行也可以使用maven進行下載
<!-- https://mvnrepository.com/artifact/io.appium/java-client -->
<dependency>
<groupId>io.appium</groupId>
<artifactId>java-client</artifactId>
<version>6.1.0</version>
</dependency>
安裝appium Server
appium Server是用nodejs運行的,基于js開發(fā)出來的.Appium組織為了方便大家安裝使用制作了一個可執(zhí)行程序appiumDesktoop
把nodejs運行環(huán)境,appiumServer和一些工具打包在了里面了,只需要簡單的下載安裝就可以了
「Appium-windows-1.15.1.exe」https://www.aliyundrive.com/s/vqSgSGpw78y安裝AndroidJDK
百度androidSDK進行下載,下載完畢后配置ANDROID_HOME,配置adb命令monkey命令等地址即可安裝javaSDK
需要用到androidSDK而androidSDK需要用到JAVA的JDK環(huán)境.所以在這里也需要安裝一下java的JDK
訪問地址:配置JAVA_HOME和bin和jre\bin即可:「jdk-8u211-windows-x64.exe」https://www.aliyundrive.com/s/FSMV3bbxCvd連接手機/模擬器
上述環(huán)境都準備好,要自動化手機app需要,在你運行程序的電腦上用USB線或者wifi連接上你的安卓手機,進入手機設置->關于手機,不斷點擊版本號菜單,推出上級菜單,就會出現(xiàn)一個開發(fā)者模式設置按鈕進入后啟動USB調試即可
連接好以后輸入adb devices -l 命令來列出連接在電腦上的安卓設備.,點擊回車如果輸出一下內容則表示連接成功可以進行自動化了
注意:輸入這個可以獲取當前正在運行app的報名和activity: adb shell dumpsys window | findstr mCurrentFocus
快速入門
from appium import webdriver
from selenium.webdriver.common.by import By
from appium.webdriver.extensions.android.nativekey import AndroidKey
desired_caps = {
'platformName': 'Android', # 被測手機是安卓
'platformVersion': '8', # 手機安卓版本
'deviceName': 'xxx', # 設備名巧鸭,安卓手機可以隨意填寫
'appPackage': 'tv.danmaku.bili', # 啟動APP Package名稱
'appActivity': '.ui.splash.SplashActivity', # 啟動Activity名稱
'unicodeKeyboard': True, # 使用自帶輸入法瓶您,輸入中文時填True
'resetKeyboard': True, # 執(zhí)行完程序恢復原來輸入法
'noReset': True, # 不要重置App
'newCommandTimeout': 6000,
'automationName' : 'UiAutomator2'
# 'app': r'd:\apk\bili.apk',
}
# 連接Appium Server,初始化自動化環(huán)境
driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
# 設置缺省等待時間
driver.implicitly_wait(5)
# 如果有`青少年保護`界面纲仍,點擊`我知道了`
iknow = driver.find_elements(By.ID, "text3")
if iknow:
iknow.click()
# 根據id定位搜索位置框呀袱,點擊
driver.find_element(By.ID, 'expand_search').click()
# 根據id定位搜索輸入框,點擊
sbox = driver.find_element(By.ID, 'search_src_text')
sbox.send_keys('開心的')
# 輸入回車鍵巷折,確定搜索
driver.press_keycode(AndroidKey.ENTER)
# 選擇(定位)所有視頻標題
eles = driver.find_elements(By.ID, 'title')
for ele in eles:
# 打印標題
print(ele.text)
input('**** Press to quit..')
driver.quit()
appium2的find_element寫法
注意:Appium Python 現(xiàn)在已經升級到 2.x 大版本压鉴,依賴 Selenium 4 以后崖咨, 下面這種 find_element_by* 方法都作為過期不贊成的寫法
driver.find_element_by_id('username').send_keys('byhy')
運行會有告警锻拘,都要寫成下面這種格式
from selenium.webdriver.common.by import By
wd.find_element(By.ID, 'username').send_keys('byhy')
而后續(xù)還有 Appium獨有的查找方式,比如
driver.find_element_by_accessibility_id('byhy')
driver.find_element_by_android_uiautomator(code)
要改成
from appium.webdriver.common.appiumby import AppiumBy
driver.find_element(AppiumBy.ACCESSIBILITY_ID, 'byhy')
driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR, code)
# 這樣也可以根據ID
wd.find_element(AppiumBy.ID, 'username').send_keys('byhy')
定位元素
從示例代碼击蹲,大家就可以發(fā)現(xiàn)署拟,和Selenium Web自動化一樣,要操作界面元素歌豺,必須先 定位(選擇)元素推穷。
Appium是基于Selenium的,所以 和 Selenium 代碼 定位元素的 基本規(guī)則相同:
- find_element_by_XXX 方法类咧,返回符合條件的第一個元素馒铃,找不到拋出異常
- find_elements_by_XXX 方法,返回符合條件的所有元素的列表痕惋,找不到返回空列表
- 通過 WebDriver 對象調用這樣的方法区宇,查找范圍是整個界面
- 通過 WebElement 對象調用這樣的方法,查找范圍是該節(jié)點的子節(jié)點
界面元素查看工具
做 Selenium Web 自動化的時候值戳,要找到元素议谷,我們是通過瀏覽器的開發(fā)者工具欄來查看元素的特性,根據這些特性(屬性和位置)堕虹,來定位元素
Appium 要自動化手機應用卧晓,同樣需要工具查看界面元素的特征芬首。
常用的查看工具是: Android Sdk包中的 uiautomateviewer 和 Appium Desktop 中的 Appium Inspector
- uiautomateviewer:安卓查看APP界面元素,最常用的就是 Android SDK 中的工具 uiautomateviewer 逼裆,它在SDK目錄目錄 的 tools\bin 目錄中
和Selenium一樣郁稍,我們要定位選擇元素,也是根據元素的特征胜宇,包括
元素的屬性
元素的相對位置(相對父元素艺晴、兄弟元素等) - Appium Inspector:Appium Desktop 中的 Appium Inspector 也可以查看元素。它的一個優(yōu)點是可以直接驗證 選擇表達式是否能定位到元素
- 根據ID
在Selenium Web自動化教程里掸屡,我們說過封寞,如果能根據ID選擇定位元素,最好根據ID仅财,因為通常來說ID是唯一的狈究,所以根據ID選擇 效率高。
在安卓應用自動化的時候盏求,同樣可以根據ID查找抖锥。
但是這個ID ,是安卓應用元素的 resource-id 屬性:
如:resource-id com.phi.letter.letterphi:id/data_title
其中data_title就是該元素的ID
from appium.webdriver.common.appiumby import AppiumBy
eles = driver.find_elements(AppiumBy.ID, 'data_title')
- 根據CLASS NAME
安卓界面元素的 class屬性 其實就是根據元素的類型碎罚,類似web里面的tagname磅废, 所以通常不是唯一的。
通常荆烈,我們根據class 屬性來選擇元素拯勉, 是要選擇多個而不是一個。
當然如果你確定 要查找的 界面元素的類型 在當前界面中只有一個憔购,就可以根據class 來唯一選擇宫峦。
使用如下代碼
from appium.webdriver.common.appiumby import AppiumBy
driver.find_elements(AppiumBy.CLASS_NAME,'android.widget.TextView')[3].click()
- 根據ACCESSIBILITY ID
元素的 content-desc 屬性是用來描述該元素的作用的。
如果要查詢的界面元素有 content-desc屬性玫鸟,我們可以通過它來定位選擇元素导绷。
使用如下代碼
from appium.webdriver.common.appiumby import AppiumBy
driver.find_element(AppiumBy.ACCESSIBILITY_ID, '找人')
- Xpath
Appium 也支持通過 Xpath選擇元素。
但是其可靠性和性能不如 Selenium Web自動化屎飘。因為Web自動化對Xpath的支持是由瀏覽器實現(xiàn)的妥曲,而Appium Xpath的支持是 Appium Server實現(xiàn)的。
畢竟钦购,瀏覽器產品的成熟度比Appium要高很多檐盟。
當然,Xpath是標準語法肮雨,所以這里表達式的語法規(guī)則和 以前學習的Selenium里面Xpath的語法是一樣的遵堵,比如
from appium.webdriver.common.appiumby import AppiumBy
driver.find_element(AppiumBy.XPATH, '//ele1/ele2[@attr="value"]')
注意:
selenium自動化中, xpath表達式中每個節(jié)點名是html的tagname。
但是在appium中陌宿, xpath表達式中 每個節(jié)點名 是元素的class屬性值锡足。
比如:要選擇所有的文本節(jié)點,就使用如下代碼
# 定位text
driver.find_element_by_xpath("http://*[@text='掃一掃']").click()
# 定位 resource-id
driver.find_element_by_xpath("http://*[@resource-id='com.taobao.taobao:id/tv_scan_text']").click()
# 也可以聯(lián)合@resource-id屬性和@text文本屬性來下定位
driver.find_element_by_xpth("http://*[@resource-id='com.taobao.taobao:id/tv_scan_text'][@text='掃一掃']").click()
# 定位搜索框 //class屬性
driver.find_element_by_xpath("http://android.widget.EditText").click()
# 定位搜索框 //*[@class='class屬性']
driver.find_element_by_xpath("http://*[@class='android.widget.EditText']").click()
dd=driver.find_element(AppiumBy.XPATH,'//androidx.recyclerview.widget.RecyclerView/android.view.ViewGroup[1]/android.widget.TextView[1]')# xpath是從1開始的
print(dd.text)
contains模糊定位
# contains匹配text
driver.find_element_by_xpath('//*[contains(@text, "注冊/登錄")]').click()
time.sleep(3)
# contains匹配textcontent-desc
driver.find_element_by_xpath("http://*[contains(@content-desc, '幫助')]").click()
安卓UIAutomator
根據id壳坪,classname舶得, accessibilityid,xpath爽蝴,這些方法選擇元素沐批,其實底層都是利用了安卓 uiautomator框架的API功能實現(xiàn)的。
參考 這里的谷歌安卓官方文檔介紹:https://developer.android.google.cn/training/testing/ui-automator
也就是說蝎亚,程序的這些定位請求九孩,被Appium server轉發(fā)給手機自動化代理程序,就轉化為為uiautomator里面相應的定位函數(shù)調用发框。
其實躺彬,我們的自動化程序,可以直接告訴 手機上的自動化代理程序梅惯,讓它 調用UI Automator API的java代碼宪拥,實現(xiàn)最為直接的自動化控制。
主要是通過 UiSelector 這個類里面的方法實現(xiàn)元素定位的铣减,比如
code = 'new UiSelector().text("業(yè)務").className("android.widget.TextView")'
ele=driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR, code)
ele.click()
就是通過 text 屬性 和 className的屬性 兩個條件 來定位元素
UiSelector里面有些元素選擇的方法 可以解決 前面解決不了的問題她君。
比如
text 方法
可以根據元素的文本屬性查找元素
textContains
根據文本包含什么字符串
textStartsWith
根據文本以什么字符串開頭
textmartch 方法
可以使用正則表達式 選擇一些元素,如下
code = 'new UiSelector().textMatches("^我的.*")'
UiSelector 的 instance 和 index 也可以用來定位元素葫哗,都是從0開始計數(shù)缔刹, 他們的區(qū)別:
instance是匹配的結果所有元素里面 的第幾個元素
index則是其父元素的幾個節(jié)點,類似xpath 里面的*[n]
UiSelector 的 childSelector 可以選擇后代元素魄梯,比如
code = 'new UiSelector().resourceId("tv.danmaku.bili:id/recycler_view").childSelector(new UiSelector().className("android.widget.TextView"))'
ele = driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR, code)
注意: childSelector后面的引號要框住整個 子 uiSelector 的表達式
目前有個bug:只能找到符合條件的第一個元素桨螺,參考appium 在github上的 issues:
https://github.com/appium/java-client/issues/150
界面操作
- click點擊
最常見的操作之一宾符,使用 WebElement 對象的 click 方法 - tap點按
WebElement 對象的 tap 方法和 click 類似酿秸,都是點擊界面。
但是最大的區(qū)別是魏烫, tap是 針對坐標 而不是針對找到的元素辣苏。
為了保證自動化代碼在所有分辨率的手機上都能正常執(zhí)行,我們通常應該使用click方法哄褒。
但有的時候稀蟋,我們難以用通常的方法定位元素, 可以用這個tap方法呐赡,根據坐標來點擊
既然tap是用坐標來點擊界面的退客,我們怎么知道這個元素的坐標呢?
大家還記得用inspect 查看該元素的屬性中擅编,有一個 bounds 屬性嗎添谊?
它就是表示元素的左上角蜜托,右下角坐標的 坐標砌溺。
我們還可以使用 UIAutomatorviewer 直接光標移動套媚,看右邊的屬性提示碴裙。
tap 方法可以像這樣進行調用
driver.tap([(850,1080)],300)
它 有 兩個參數(shù):
第一個參數(shù)是個列表屉来,表示點擊的坐標蓬抄。
注意最多可以有5個元素务傲,代表5根手指點擊5個坐標凉当。所以是list類型。
如果我們只要模擬一根手指點擊屏幕售葡,list中只要一個元素就可以了
第二個參數(shù) 表示 tap點按屏幕后 停留的時間看杭。
如果點按時間過長,就變成了長按操作了挟伙。 - 輸入
使用 WebElement 對象的 send_keys 方法 - 滑動
我們做移動app測試的時候泊窘,經常需要滑動界面。
怎么模擬滑動呢像寒? WebDriver對象的 swipe方法烘豹,就提供了這個功能
比如
driver.swipe(start_x=x, start_y=y1, end_x=x, end_y=y2, duration=800)
前面4個參數(shù) 是 滑動起點 和 終點 的x、y坐標诺祸。
第5個參數(shù) duration是滑動從起點到終點坐標所耗費的時間携悯。
注意這個時間非常重要,在屏幕上滑動同樣的距離筷笨,如果時間設置的很短憔鬼,就是快速的滑動。
比如:一個翻動新聞的界面胃夏,快速的滑動轴或,就會是掃動的動作,會導致內容 慣性 滾動很多仰禀。 - 按鍵
前面的示例代碼中已經使用過 調用 press_keycode 方法照雁,就能模擬 按鍵動作,包括安卓手機的實體按鍵和 鍵盤按鈕答恶。
from appium.webdriver.extensions.android.nativekey import AndroidKey
# 輸入回車鍵饺蚊,確定搜索
driver.press_keycode(AndroidKey.ENTER)
按鍵的定義,可以參考這篇文檔 https://github.com/appium/python-client/blob/master/appium/webdriver/extensions/android/nativekey.py
- 長按\雙擊\移動
Appium的 TouchAction 類提供了更多的手機操作方法悬嗓,比如:長按污呼、雙擊、移動
from appium.webdriver.common.touch_action import TouchAction
# ...
actions = TouchAction(driver)
actions.long_press(element)
actions.perform()
- 查看通知欄
打開通知欄
安卓手機包竹, 查看通知欄的動作可以是從屏幕頂端下滑來查看通知燕酷。
我們剛剛學過滑動籍凝,感興趣的朋友可以自己試試,關鍵是要找對滑動的起始點和滑動距離苗缩。
更方便的静浴,我們可以使用如下代碼,直接打開通知欄
driver.open_notifications()
或者使用滑動
driver.swipe(start_x=10, start_y=0, end_x=10, end_y=1000, duration=500)
收起通知欄
收起通知欄挤渐,可以使用前面介紹的模擬按鍵苹享, 發(fā)出返回按鍵 的方法
driver.back()
driver.keyevent(4)
我們自動化過程中,可能需要截屏手機浴麻,并且下載到指定目錄中得问,就可以在我們的Python程序中這樣寫
import os
os.system('adb shell screencap /sdcard/screen3.png && adb pull /sdcard/screen3.png')
特別是,還可以通過adb 使用 am(activity manager) 和pm (package manager) 兩個工具软免, 可以啟動 Activity宫纬、強行停止進程、廣播 intent膏萧、修改設備屏幕屬性漓骚、列出應用、卸載應用等榛泛。
關閉APP
使用 driver.terminate_app(appPackage) 即可
內嵌網頁自動化
- 內嵌網頁的混合App
很多移動App 都是 Hybrid(混合) 應用蝌蹂。
混合應用主要是指 它的一部分是原生界面和代碼孤个,而另一部分是內嵌網頁 。
現(xiàn)在基本上需要打開網頁瀏覽的app都是 混合app沛简,比如微信齐鲤、支付寶等。
微信的sms界面是原生代碼實現(xiàn)的椒楣,而打開某個朋友圈给郊,或者別人發(fā)來的的鏈接部分則是 web部分。
App中的內嵌的展示網頁內容的模塊捧灰,我們稱之為 webview 淆九。
我們自動化的時候如果需要操作內嵌webview中的網頁內容,該怎么做呢凤壁? - 修改編譯App
前面講過吩屹,Appium 的原則是不修改應用本身,就可以對應用進行自動化拧抖。
但是,這里要違背一下 appium的原則免绿。
要對App內嵌網頁進行自動化唧席,首先要請 開發(fā)人員修改源代碼,保證對webview 對象加入setWebContentsDebuggingEnabled 的調用。
安卓應用淌哟,修改java代碼迹卢,如下所示:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 找到 webview 對象
WebView myWebView = (WebView) findViewById(R.id.jcywebview);
// 添加打開 webview內容debug開關
myWebView.setWebContentsDebuggingEnabled(true);
};
然后,編譯出一個支持自動化的版本徒仓。
否則無法對webview中的內容進行自動化操作腐碱。
- 用Chrome查看App內嵌網頁
編譯產生了 支持自動化 的App,接下來我們就可以安裝到手機上掉弛,進行內嵌網頁的自動化了症见。
App內嵌網頁的自動化,也是使用 Selenium殃饿。 和電腦上自動化Chrome瀏覽器本質是一樣的谋作。
因為 安卓手機內嵌webview 基本上就是 手機版的 Chrome瀏覽器 。
但是乎芳,因為網頁內容在手機中呈現(xiàn)遵蚜,不能像電腦瀏覽器那樣吭净,打開開發(fā)者工具肴甸,查看元素內容。
那我們怎么查看元素的屬性特征不撑,來定位選擇元素呢焕檬?
這里面要分兩種情況:
webview不依賴App環(huán)境
這種情況:App的內嵌 webview 和 native部分沒有交互 的实愚。
webview 只是打開一個固定的網址(一般是該公司的手機網址)而已腊敲。
這種情況碰辅,我們要查看webview內容非常簡單没宾。
因為其實和手機沒有關系循衰。
直接用Chrome瀏覽器F12里面的手機模式打開對應的網頁,即可伐蒋。-
webview依賴App環(huán)境
首先先鱼,確保我們的應用運行,然后應用訪問webview頁面,打開電腦瀏覽器地址欄輸入 chrome://inspect 型型,出現(xiàn)如下所示界面
image.png(括號中說的是webview版本號)
webview版本也比較老的,就會有問題绷落, 盡量使用新手機進行自動化
點擊 inspect即可查看
webview自動化代碼 和 電腦上瀏覽器的自動化 基本差不多砌烁。
但是有一點要注意:
手機App中 webview里面的網頁內容函喉, 是在一個獨立于應用native部分的環(huán)境里面的管呵。
而缺省情況下捐下,find_element_by_xxx 這樣的代碼選擇元素, Appium 只會在 native 部分的界面尋找元素坷襟。 肯定找不到元素婴程。
Appium 把一個界面環(huán)境 稱之為一個 context 排抬。
native 部分的 context 名字為 NATIVE_APP , 而webview部分的context則為 WEBVIEW_XXX (XXX部分是 應用的 app package名)
我們怎么查看當前有哪些context呢蹲蒲?
我們的代碼通過 driver 對象的 contexts 屬性來獲取届搁,也就是 driver.contexts卡睦。
driver 對象的 current_context 屬性對應當前的 context 對象表锻。
大家可以打開自動化代碼乞娄, 添加如下內容
print(driver.contexts)
執(zhí)行一下仪或,解釋一下范删,可以發(fā)現(xiàn)結果如下旨巷。
['NATIVE_APP', 'WEBVIEW_stetho_com.phi.letter.letterphi']
我們的應用中添忘, webview 的 context 就是 WEBVIEW_stetho_com.phi.letter.letterphi
而當前的context 是’NATIVE_APP'懈万, 所以當前的自動操作都是在native context里面的進行的会通。
要對該webview里面的網頁內容進行自動化操作涕侈,必須先將當前的context切換為 webview的context木张,怎么切呢端三?
使用 switch_to.context
driver.switch_to.context('WEBVIEW_stetho_com.phi.letter.letterphi')
使用該語句如果webview版本和chrome驅動版本不一致則會報版本錯誤問題此時我們需要查看報錯的版本,下載對應的chrome版本驅動包即可
版本對應查看地址:https://raw.githubusercontent.com/appium/appium-chromedriver/master/config/mapping.json
chrome驅動包下載地址:http://chromedriver.storage.googleapis.com/index.html
先點擊 Advanced 設置項
然后在 下圖位置 寫上你的 老版本的 chromedriver 的路徑
好团赁,現(xiàn)在我們修改代碼欢摄,如下所示
from selenium.webdriver.common.by import By
driver.switch_to.context('WEBVIEW_com.example.jcy.wvtest')
driver.find_element(By.ID, 'index-kw').send_keys('開心的小哈')
driver.find_element(By.ID, 'index-bn').click()
執(zhí)行一下怀挠,發(fā)現(xiàn)可以自動化了
那么怎么切換回 native app 進行自動化呢嫌变?
當然是 繼續(xù)使用 switch_to.context 躬它,如下
driver.switch_to.context('NATIVE_APP')
手機瀏覽器網頁自動化
有的公司開發(fā)了手機版網站倘待,直接用手機瀏覽器打開的组贺,比如啊奄,xiaomi 京東等。
并不是 手機App
這種手機網頁庄新,我們怎么 程序自動化呢择诈?
首先羞芍,必須在手機上安裝谷歌瀏覽器涩金。
以百度為例步做,
首先啟動 Appium Desktop。
然后斥滤,我們的自動化程序代碼如下所示:
from appium import webdriver
from selenium.webdriver.common.by import By
desired_caps = {}
desired_caps['platformName'] = 'Android'
desired_caps['platformVersion'] = '7'
desired_caps['deviceName'] = 'test'
desired_caps['browserName'] = 'Chrome'
desired_caps['newCommandTimeout'] = 6000
driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
driver.implicitly_wait(10)
driver.get('http://www.baidu.com')
driver.find_element(By.ID, 'index-kw').send_keys('開心的小哈')
driver.find_element(By.ID, 'index-bn').click()
driver.quit()
更多了解:AndroidViewClient UiAutomator2
在使用過程中出現(xiàn)的問題
- 點擊web頁面元素時如果使用ID,NAME定位結果出現(xiàn)
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.InvalidArgumentException: Message: invalid argument: invalid locator
(Session info: chrome=88.0.4324.93)
Stacktrace:
Backtrace:
GetHandleVerifier [0x000BB963+483]
GetHandleVerifier [0x000BB941+449]
GetHandleVerifier [0x00463308+3832712]
GetHandleVerifier [0x004863A7+3976231]
GetHandleVerifier [0x004A8822+4116642]
GetHandleVerifier [0x0049B43A+4062394]
GetHandleVerifier [0x004A7159+4110809]
GetHandleVerifier [0x0049B2EB+4062059]
GetHandleVerifier [0x0047ED14+3945876]
GetHandleVerifier [0x0047FBCE+3949646]
GetHandleVerifier [0x0047FB59+3949529]
Ordinal0 [0x0007B5CC+46540]
Ordinal0 [0x00079F53+40787]
Ordinal0 [0x00079B12+39698]
GetHandleVerifier [0x00381468+2907368]
GetHandleVerifier [0x001C71EE+1096302]
GetHandleVerifier [0x00183E8D+821005]
GetHandleVerifier [0x0018396B+819691]
GetHandleVerifier [0x00183881+819457]
GetHandleVerifier [0x001AF463+998627]
BaseThreadInitThunk [0x76B4FA29+25]
RtlGetAppContainerNamedObjectPath [0x77B57A7E+286]
RtlGetAppContainerNamedObjectPath [0x77B57A4E+238]
(No symbol) [0x00000000]
問題原因導致:如果 chromedriver 在 W3C 模式下工作将鸵,則會出現(xiàn)這種情況。W3C標準只聲明CSS和XPATH定位器佑颇,其中id和名稱的位置已被刪除為過時顶掉,因為CSS涵蓋了它們。
有三種可能的解決方法:
- 更新不受支持的定位器
- 將 chromedriver 強制執(zhí)行 JSONWP 模式(將 chromedriver 選項設置為w3cfalse)
- 將過時的定位器類型傳遞給客戶端代碼中的轉換方法挑胸,該方法會自動將它們升級到CSS定位器(這是Selenium lib當前正在做的事情)
其中第二個需要在開啟時配置
desired_caps['chromeOptions'] = {'w3c': False}
desired_caps['showChromedriverLog'] = data['showChromedriverLog']
即可;