企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
[TOC] # appium基本使用 * 夜神模拟器win7系统下的连接方法:**`adb connect 127.0.0.1:62001`** * 夜神模拟器win10系统下的连接方法:**`adb connect 127.0.0.1:62025`** * deviceName型号 **`adb devices -l`** * 查看当前运行的APP的包名和打开的Activity **`adb shell "dumpsys window | grep mCurrentFocus"`** ~~~ 遇坑排查: 上述 adb shell "dumpsys window | grep mCurrentFocus" 得到的数据不对(也不能说不对,APP首次启动,启动的不是首页) 获取首次应用的活动名称可以通过 启动一次随机 monkey命令来获取 adb shell monkey -p com.XXXX.XXX -vvv 1 ·adb devices 有多个设备时,连接其中一个设备 adb -s 设备名 shell adb -s 8BN******413 shell 获取到的数据正确,app启动成功 ~~~ ![](https://img.kancloud.cn/e3/3d/e33d48a18717058749b32e2786fa7649_992x163.png) 配置Python连接手机app ~~~ desired = { "platformName": "Android", "platformVersion": "设备版本", "deviceName": "设备名称", "appPackage": "包名", "appActivity": "activity名称", "unicodeKeyboard": "True", "restKeyboard": "True" } ~~~ 首先需要现在appium中开启服务 ![](https://img.kancloud.cn/44/d3/44d39e3f1f8302e2d49a1d31b3a19a0c_650x600.png) 点击后如下 ![](https://img.kancloud.cn/e5/c8/e5c8aa57f95c5837f44b905145b3e672_650x600.png) 在appium中配置json文件 ~~~ { "platformName": "Android", "platformVersion": "设备版本", "deviceName": "设备名称", "appPackage": "包名", "appActivity": "activity名称", "unicodeKeyboard": "True", "restKeyboard": "True" } ~~~ 然后点击 ![](https://img.kancloud.cn/f7/2c/f72cc6f2f38eae68c0433b1fee1bce77_705x619.png) 填写json内容 ![](https://img.kancloud.cn/75/70/757052084b4e51f484f24cee99d362d5_1080x570.png) 填写完成后,点击保存 ![](https://img.kancloud.cn/55/a8/55a851abfdb2af85db057524636ef689_1080x570.png) 当然你也可以保存该配置至电脑中 ![](https://img.kancloud.cn/cf/97/cf97eb5e9f2a134e44efac0f89c98a22_1350x641.png) ![](https://img.kancloud.cn/25/34/2534612da0db58bc7642f602db7b333d_594x288.png) > ### 定位元素 `start_session`就可以开始定位元素了 ![](https://img.kancloud.cn/cf/62/cf623d03a042d6b61c25f63c90f46c4a_933x582.png) 基本使用 ![](https://img.kancloud.cn/b8/d3/b8d396884e48f018338adfb5b0cd5197_1440x854.png) 判断属性是否唯一 ![](https://img.kancloud.cn/23/6b/236b3f4a376518e92adfdc9b68b9c02a_693x273.png) ![](https://img.kancloud.cn/e1/5c/e15cb3571fbbf99808f4306d16fbdb85_581x339.png) ![](https://img.kancloud.cn/d2/22/d22202b08fb4eb3a6e03579ce100ab51_531x405.png) > ### 基本定位 ~~~ from appium import webdriver from time import sleep # 配置需要操作的手机以及app desired = { "platformName": "Android", "platformVersion": "5.1.1", "deviceName": "127.0.0.1:62001", "appPackage": "com.mymoney", "appActivity": "com.mymoney.biz.splash.newguide.NewGuideActivity", "unicodeKeyboard": "True", "restKeyboard": "True" } # 连接appium,打开app d = webdriver.Remote('http://127.0.0.1:4723/wd/hub',desired) sleep(5) # 点击下一步,使用id定位 d.find_element_by_id('com.mymoney:id/next_btn').click() sleep(3) # 再次点击下一步,使用class定位 d.find_element_by_class_name('android.widget.Button').click() sleep(3) # 点击开始随手记 d.find_element_by_xpath('/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.support.v4.view.ViewPager/android.widget.LinearLayout[2]/android.widget.LinearLayout[2]/android.widget.Button[1]').click() sleep(10) # 关闭app d.close_app() ~~~ > ### UIAutomator定位 使用方法 find\_element\_by\_android\_uiautomator() 可以运用UiAutomator元素定位。 UiAutomator提供一下三种方式来定位: •id定位`d.find_element_by_android_uiautomator('new UiSelector().resourceId("id的值")')` •text定位`d.find_element_by_android_uiautomator('new UiSelector().text("text的内容")')` •class name定位`d.find_element_by_android_uiautomator('new UiSelector().className("className的值")')` > ### 定位一组元素 > ### Swipe 两点之间的滑动操作 我们在使用App的过程中,经常会在屏幕上进行滑动的操作,如,刷新新闻,刷朋友圈等,会做上下滑动的动作;如果是看图片,就会左右移动。在Appium里面,我们是用swipe()这个方法来实现这个操作。 ![](https://img.kancloud.cn/cc/74/cc742f18fff9d35909454596761ac104_552x357.png) 语法: `swipe(起始横坐标,起始纵坐标,目标横坐标,目标纵坐标)` 获取屏幕尺寸`d.get_window_size()`获取屏幕大小,以**词典**的方式返回 想右滑动,y轴不变,x轴由小到大即可 ~~~ # 获取屏幕大小,以词典的方式返回 size = d.get_window_size() width = size['width'] height = size['height'] x1 = 0.2 * width x2 = 0.9 * width y = 0.5*height d.swipe(x1,y,x2,y) ~~~ > ### 连续滑动 swipe滑动操作,一般是两点之间的滑动,而实际使用过程中用户可能要进行一些多点连续滑动操作。如手势密码操作,切西瓜等场景。那么在Appium中该如何模拟这类操作呢? TouchAction TouchAction包含一些列操作,比如按压、长按、点击、移动、暂停。由这些不同操作可以组成一套动作。使用TochAction需要先导入对应的模块: `from appium.webdriver.common.touch_action import TouchAction` 连续滑动需要导入`from appium.webdriver.common.touch_action import TouchAction` * 按压 方法:press() 按压一个元素或坐标点(x,y)。 ~~~ press(element) press(x,y) ~~~ * 长按 方法:相比press()方法,long\_press()多了一个入参,就是长按的时间。duration以毫秒为单位。1000表示按一秒钟。其用法与press()方法相同。 ~~~ long_press(element,duration=1000) long_press(x,y,duration=1000) ~~~ * 点击 方法:tap() 对一个元素或控件执行点击操作。用法参考press()。 ~~~ tap(element) tap(x,y) ~~~ * 移动 方法:move\_to() 将指针从上一个点移动到指定的元素或点。 ~~~ move_to(element) move_to(x,y) ~~~ * 暂停 方法:wait()暂停脚本的执行,单位为毫秒。 ~~~ wait(ms) ~~~ * 释放 方法release() ,我们滑动总要停止吧?怎么停止?就是用这个方法停止。 ~~~ release() ~~~ * 执行 方法:perform() 把要执行的操作发送到Appium服务器,即让要执行的操作生效。 ~~~ perform() ~~~ **示例代码** ~~~ from appium import webdriver from time import sleep from appium.webdriver.common.touch_action import TouchAction # 配置需要操作的手机以及app desired = { "platformName": "Android", "platformVersion": "5.1.1", "deviceName": "127.0.0.1:62001", "appPackage": "com.mymoney", "appActivity": "com.mymoney.biz.splash.newguide.NewGuideActivity", "unicodeKeyboard": True, "restKeyboard": True } # 连接appium,打开app d = webdriver.Remote('http://127.0.0.1:4723/wd/hub',desired) sleep(5) # UIAutomator定位之id定位 d.find_element_by_android_uiautomator('new UiSelector().resourceId("com.mymoney:id/next_btn")').click() sleep(2) # 再次点击下一步,使用class定位 d.find_element_by_android_uiautomator('new UiSelector().className("android.widget.Button")').click() sleep(2) # 通过text定位,进入首页 d.find_element_by_android_uiautomator('new UiSelector().text("开始随手记")').click() sleep(10) # 点击更多 d.find_element_by_id('com.mymoney:id/nav_setting_btn').click() sleep(2) # 往上滑动 # # 获取屏幕大小,以词典的方式返回 size = d.get_window_size() width = size['width'] height = size['height'] x = 0.5 * width y1 = 0.2 * height y2 = 0.9 * height d.swipe(x,y2,x,y1) sleep(2) # 点击高级 d.find_element_by_android_uiautomator('new UiSelector().text("高级")').click() sleep(2) d.find_element_by_android_uiautomator('new UiSelector().text("密码与手势密码")').click() sleep(2) d.find_element_by_android_uiautomator('new UiSelector().text("手势密码保护")').click() sleep(2) print('连续滑动') TouchAction(d).press(x=169,y=190).wait(1000).move_to(x=274,y=190).move_to(x=270,y=293).move_to(x=170,y=382).release().perform() sleep(3) d.close_app() ~~~ > ### H5元素的定位 在混合开发的App中,经常会有内嵌的H5页面。针对这种场景直接使用前面所讲的方法来进行定位是行不通的,因为前面的都是基于Andriod原生控件进行元素定位,而Web网页是单独的B/S架构,两者的运行环境不同因此需要进行上下文(context)切换,然后对H5页面元素进行定位操作。 什么是context呢?在程序中context我们可以理解为当前对象在程序中所处的一个环境。 比如前面提到的App一个界面是属于Activity类型,也就是Android界面环境,但是当访问内嵌的网页是属于另外一个环境(网页环境),两者处于不同的一个环境。 * 获取所有的上下文`contexts`,以列表的形式返回 ~~~ all_context = d.contexts print(all_context) ~~~ * 切换上下文`switch_to.context()` ~~~ all_context = d.contexts d.switch_to.context(all_context[1]) ~~~ * H5操作的环境搭建 1. 手机与电脑连接,通过adb devices可查看到此设备。 2. 电脑端必须安装chrome浏览器(selenium环境搭建好即可)。 3. App Webview[开启debug模式](https://www.jianshu.com/p/ebd9736ad274)(注:此步骤,一般需要App开发人员开启。) 4. 在电脑端Chrome浏览器地址栏输入`chrome://inspect/#devices`,进入调试模式 5. 打开app对应的h5页面,在`chrome://inspect/#devices`地址中,检查是否显示对应的webview,如没有,则当前未开启调试模式。 ![](https://img.kancloud.cn/19/44/19443326bb341a0708bbe75c9ab3167c_999x484.png) 上图App已经开启了开启调试模式。 6. 下载与手机系统浏览器的版本相对应的驱动 比如我的版本是`74.0.3729.136`,我就需要下载相对应版本的谷歌浏览器驱动 下载下来之后创建一个文件夹存放该驱动,并且解压 比如,我在**D**盘创建了一个`app_chromederiver`目录,将驱动移动进去并解压 ![](https://img.kancloud.cn/0b/a8/0ba87570be16988cefe2f0a942391a96_694x355.png) 另外在脚本中的`desired`中增加一项`chromedriverExecutable`指定驱动位置即可 比如我的: ~~~ # 配置需要操作的手机以及app desired = { "platformName": "Android", "platformVersion": "5.1.1", "deviceName": "127.0.0.1:62001", "appPackage": "com.wondershare.drfone", "appActivity": "com.wondershare.drfone.ui.activity.Main2Activity", "unicodeKeyboard": True, "restKeyboard": True } # 由于appium自带了一个chromedriver,所以我们需要指定appium使用我们下载下来的对应版本的驱动 # 在desired中,增加一个key>>> chromedriverExecutable,它的值就是指定的驱动位置 desired['chromedriverExecutable'] = R"D:\app_chromederiver\chromedriver.exe" ~~~