1.准备工作
java-jdk安装(appium启动必须要求安装Java)
appium安装
adb安装
appium 模块Appium-Python-Client安装
2.各个应用安装说明
java-jdk
这个安装,需要注意环境变量的配置
配置jdk,新建环境变量(系统变量) JAVA_HOME,如图所示:
系统变量->找到 Path 变量->编辑->在变量值的末尾添加;%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin
如果在你下载的文件里面找不到jre/bin的文件,即下面这个目录,一定要以管理员模式打开cmd,进入java的jdk安装目录,输入
bin\jlink.exe --module-path jmods --add-modules java.desktop --output jre 回车即可。
检验方式
输入java -version,查看版本。
参考链接:https://zhuanlan.zhihu.com/p/360519888
Appium
是一个开源工具,用于自动化 iOS 手机、 Android 手机和 Windows 桌面平台上的原生、移动 Web 和混合应用。连接手机,启动安装后界面如下
下载链接:https://appium.io/
adb安装
这个目的是为了下发手机相关命令,下载后注意手动去配置环境变量。
下载链接:https://developer.android.google.cn/studio?hl=zh-cn
Appium-Python-Client
这个强烈建议不要下载最新版本,后续自动化测试,会导致和appium某些功能不适配,建议下载Appium-Python-Client版本在1.3.0或1.3.0以下。
(过程中可能会出现Method has not yet been implemented的报错,此错误是因为appium sever的版本和Appium-Python-Client 的版本不一致)
下载链接:http://appium.io/downloads.html
2.appium连接手机配置
我的p40pro手机,配置如下:
启动后效果:
python启动,基本参数配置如下
from appium import webdriver from selenium.webdriver.common.by import By desired_caps = { "platformName": "Android", # 操作系统 "deviceName": "UQG5T20610006585", # 设备 ID adb devices "platformVersion": "10", # 设备版本号 "appPackage": "com.tencent.mm", # app 包名 "appActivity": "com.tencent.mm.ui.LauncherUI", # app 启动时主 Activity 'noReset': True, # 是否保留 session 信息,可以避免重新登录 'autoLaunch Appium': True, 'automationName': 'UiAutomator1', 'unicodeKeyboard': True, # 使用 unicodeKeyboard 的编码方式来发送字符串 'resetKeyboard': False # 将键盘给隐藏起来 } driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps) print("微信启动")
这里需要注意其中的automationName这两个参数,如果这个参数报错,那么可能是UiAutomator2,以报错说明为准
以下是参考网上,微信对删除自己的人的清除操作的代码,有一下几个注意点:
1. find_element_by_id方法的废弃,现在统一为了find_element
2.手机上滑,坐标系的取值,即driver.swipe(x1, y1, x1, y2, duration=500)方法,y2与y1之间尽量差距小一点,滑动点小一点,这样获取微信好友不容易漏掉
3.代码中所有的定位元素id参数修改,如driver.find_elements(By.ID, 'com.tencent.mm:id/hga')中的com.tencent.mm:id/hga。
微信版本变化,它的id值可能都会变化。我拿过来这段代码,当中所有的定位元素基本都做了修改
4.微信好友名称的特殊化处理,有的微信名称里面,有花花草草猫猫狗狗,特殊表情符号这些。虽然都能获取到,但是逐个取值,搜索栏搜索定位过程可能导致搜索不到最终报错
以下是代码,对下面代码基本吃透,appium算是上手了
import time from appium import webdriver from selenium.webdriver.common.by import By # 判断元素是否存在 def is_element_exist(element, timeout=3): count = 0 while count < timeout: souce = driver.page_source if element in souce: return True else: count += 1 time.sleep(1) return False desired_caps = { "platformName": "Android", # 操作系统 "deviceName": "UQG5T20610006585", # 设备 ID adb devices "platformVersion": "10", # 设备版本号 "appPackage": "com.tencent.mm", # app 包名 "appActivity": "com.tencent.mm.ui.LauncherUI", # app 启动时主 Activity 'noReset': True, # 是否保留 session 信息,可以避免重新登录 'autoLaunch Appium': True, 'automationName': 'UiAutomator1', 'unicodeKeyboard': True, # 使用 unicodeKeyboard 的编码方式来发送字符串 'resetKeyboard': False # 将键盘给隐藏起来 } driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps) print("微信启动") # 上拉方法 def swipe_up(distance): # distance为滑动距离,time为滑动时间 size = driver.get_window_size() # print(size) x1 = 0.5 * size['width'] y1 = 0.8 * size['height'] y2 = (0.8 - distance) * size['height'] driver.swipe(x1, y1, x1, y2, duration=500) # 获取通讯录列表 def get_address_list(flag): if flag == True: driver.find_elements(By.ID, 'com.tencent.mm:id/f2i')[1].click() # 上滑 时间越短,划得屏幕越大 swipe_up(0.2) else: swipe_up(0.21) # 获取昵称(备注) address_list = driver.find_elements(By.ID, 'com.tencent.mm:id/hga') remarks = [] for address in address_list: remark = address.get_attribute("text") # 白名单 if remark != '个人微信名字' and ("微信团队" not in remark) and ("文件传输助手" not in remark): remarks.append(remark) return remarks # 判断是否被删 def is_delete(remark, count): if count == "1": time.sleep(0.2) print('点击微信搜索框') driver.find_element(By.ID, 'com.tencent.mm:id/gss').click() time.sleep(0.1) print('在搜索框输入搜索信息') driver.find_element(By.ID, 'com.tencent.mm:id/cd6').send_keys(remark) time.sleep(0.1) print('点击搜索到的好友') driver.find_element(By.ID, 'com.tencent.mm:id/kpx').click() time.sleep(0.1) print('功能按钮展开') driver.find_element(By.ID, 'com.tencent.mm:id/b3q').click() time.sleep(0.1) print('点击转账按钮') driver.find_elements(By.ID, 'com.tencent.mm:id/ve')[5].click() time.sleep(0.1) print('跳转,开始转钱') driver.find_element(By.ID, 'com.tencent.mm:id/ffn').click() time.sleep(0.1) print('确认') driver.find_element(By.ID, 'com.tencent.mm:id/ffw').click() time.sleep(0.1) # 判断是否被删 is_exist = is_element_exist('com.tencent.mm:id/guv') if is_exist is True: return remark else: return False # 返回搜索框 def search_back(): time.sleep(0.1) driver.find_element(By.ID, 'com.tencent.mm:id/fz').click() time.sleep(0.1) driver.find_element(By.ID, 'com.tencent.mm:id/fz').click() time.sleep(0.1) # 清除搜索框,输入下一个 driver.find_element(By.ID, 'com.tencent.mm:id/k1h').click() # 删除把自己删除的人 def del_person(nicks): print('点击微信搜索框') driver.find_element(By.ID, 'com.tencent.mm:id/gss').click() for inx, val in enumerate(nicks): time.sleep(0.5) if inx == 0: print('在搜索框输入搜索信息') driver.find_element(By.ID, 'com.tencent.mm:id/cd6').send_keys(val) else: time.sleep(1) print('点击微信搜索框') driver.find_element(By.ID, 'com.tencent.mm:id/gss').click() print('在搜索框输入搜索信息') time.sleep(0.5) driver.find_element(By.ID, 'com.tencent.mm:id/cd6').send_keys(val) time.sleep(0.5) print('点击搜索到的人') driver.find_element(By.ID, 'com.tencent.mm:id/kpx').click() time.sleep(0.5) print('点击聊天对话框右上角...') driver.find_element(By.ID, 'com.tencent.mm:id/en').click() time.sleep(1) print('点击头像') driver.find_element(By.ID, 'com.tencent.mm:id/iwj').click() time.sleep(1) print('点击联系人右上角...') driver.find_element(By.ID, 'com.tencent.mm:id/en').click() time.sleep(1) print('点击删除按钮') driver.find_element(By.ID, 'com.tencent.mm:id/khu').click() time.sleep(1) print('点击弹出框中的删除') driver.find_element(By.ID, 'com.tencent.mm:id/gv3').click() if __name__ == '__main__': remarks = [] driver = webdriver.Remote("http://localhost:4723/wd/hub", desired_caps) # 打开微信需要时间 time.sleep(5) remarks1 = get_address_list(True) remarks.extend(remarks1) while True: # 是否到了通讯录末尾 is_end = is_element_exist('com.tencent.mm:id/bml') # time.sleep(0.2) remarks2 = get_address_list(False) remarks.extend(remarks2) if is_end == True: break remarks = set(remarks) print("通讯录昵称列表:", remarks) print("好友数目:", len(remarks)) time.sleep(1) dels = [] for inx, val in enumerate(remarks): rt = "" if inx == 0: rt = is_delete(val, "1") else: rt = is_delete(val, "") if rt is False: # 返回搜索框 driver.keyevent(4) search_back() # 被删除 else: dels.append(rt) time.sleep(0.1) driver.find_element(By.ID, 'com.tencent.mm:id/gv3').click() search_back() print("删除我的人:", dels) # 删除删了自己的人 del_person(dels)