前言

关于 appium 是什么之类的不再赘述,有关的博文已经很多了,本文旨在提供截至 2022 年除夕可以在 Windows 11 上复现的操作方法
虽然这篇博文被看到的时候应该只能用在 2023 年的春节了

环境配置

  1. 安装 appium desktop

  2. 安装 appium-inspector

  3. 安装 JDK

  4. 安装 MuMu 模拟器
    安装好后在 系统应用 -> 设置 -> 开发者选项 中打开 USB调试
    同时查看 设置 -> 关于平板电脑 -> Android版本,我的是 6.0.1

  5. 借助 Android Studio 安装 SDK
    首先下载+安装+运行 Android Studio ,进入到欢迎界面,再进入 SDK 管理


    安装 6.0 是因为 MuMu 模拟器是 6.0.1

  6. 进行一堆环境变量的设置
    Win+R 运行 control system -> 相关链接 -> 高级系统设置 -> 环境变量

    1. 下方环境变量区中新建

      变量名:ANDROID_HOME
      变量值:下图所示
      变量名:JAVA_HOME
      变量值:刚才 JDK 的安装目录
      如:C:\Program Files\Java\jdk-17.0.2
      变量名:CLASSPATH
      变量值:.;%JAVA_HOME%\lib;

      变量名:prog_dir
      变量值:%ANDROID_HOME%\platform-tools

      变量名:ANDROID_SWT
      变量值:%ANDROID_HOME%\tools\lib\x86_64

    2. 已有的系统变量中找到Path -> 编辑 -> 编辑文本 -> 在文末插入
      %JAVA_HOME%\bin;%ANDROID_HOME%;%ANDROID_HOME%/tools;%ANDROID_HOME%/platform-tools;

    3. 测试
      在 cmd 中运行

      C:\Users\username> java -version
      C:\Users\username> javac -version
      C:\Users\username> adb devices
      

      结果类似下图即说明设置成功

  7. 安装 appium 的 Python 驱动
    pip3 install appium-python-client

链接Android模拟器

如果在 cmd 下执行 adb devices 显示出有设备链接了那就万事大吉
但是 MuMu 应该是没办法被自动检测到的,如下位置 MuMu 告诉我们运行

adb connect 127.0.0.1:7555

appium 的准备工作

分别打开 Appium Server GUI 和 Appium Inspector,原本他们是在一起的,现在分成了两个程序

GUI:直接 Start ,此时 Edit Configuration 里面应该已经自动填上了刚才设置的JAVA_HOME 和 ANDROID_HOME

Inspector

  1. 如果你下载最新 Appium Desktop 时仍有如下提示,请把 Insepector 中的 Reomote Path 改成 /wd/hub ,否则会报错(见 Append:Failed to create session)

  2. 编辑 Desired Capabilities,我们直接用 JSON 格式

    {"platformName": "Android","deviceName": "MuMu","platformVersion": "6.0.1","appPackage": "com.tencent.mm","appActivity": ".ui.LauncherUI","newCommandTimeout": 6000,"noReset":true
    }
    

    有关 Desired Capabilities 的官方文档
    . newCommandTimeout: 一个 session 在未接收到任何命令多久后会自动关闭,默认 60s 太短了

  3. Start Session

    看到这个大大的地球我们就成功了,至此最艰难的步骤都已经完成了

  4. 补充:包名获取
    这里任意 appPackage 和 appActivity 的获取可以用以下方式,仍以微信为例:
    在 MuMu 上打开微信
    在 cmd 中运行 adb shell 进入模拟器操作系统
    运行 dumpsys window windows | grep mFocusedApp,对照一下就懂了,其中第一次运行时是在登录界面,第二次是在联系人界面,所以 appActivity 不同

  5. Inspector 演示
    点击我们想要了解的地方就可以看到 id (即 resource_id) 和相关信息了。注意它的界面不是自动同步的,必须手动点一下上面的刷新才会同步

    一些例子:



    接下来我们先放下这边的工作,先构建脚本框架

脚本编写

from appium import webdriver
from selenium.webdriver.support.ui import WebDriverWaitclass RedEnvelope():def __init__(self):self.desired_caps = {"platformName": "Android","deviceName": "MuMu","platformVersion": "6.0.1","appPackage": "com.tencent.mm","appActivity": ".ui.LauncherUI","newCommandTimeout": 6000,"noReset": True}self.driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_capabilities=self.desired_caps)# 这里4723要改成 Appium Server GUI 启动时显示的端口# 同时后面的 /wd/hub 也要根据 appium desktop 中的提示修改def login(self):print('正在登陆中——————')def main(self):self.login()R = RedEnvelope()
R.main()

以上代码和刚刚按的 Start Session 是一样的,观察模拟器会发现微信被打开了

使用 Insepctor 来分析 UI

Python 代码运行起来后,Inspector -> Attach to Session -> 选择 Session ID,对应的 Session ID 可以通过 driver 创建好后 driver.session_id 查看

print('session_id:', self.driver.session_id)

Ui Automator Viewer

Appium Inspector 其实是一个不太好的选择,一是慢,二是检测能力似乎不强,三是看不到元素层次,很多时候要点的元素被遮挡了
这里有两个现成的选择

  1. sdk\tools\bin 下的 uiautomatorviewer.bat ,但是 Java 版本必须是 Java 8
  2. sdk\tools 下的 monitor.bat

最初的环境配置中其实已经加入了与这两个软件相关的环境变量配置,以下展示 Ui Automator Viewer 的界面

这里有一个BUG,如果用 MuMu 默认的平板分辨率,打开微信的时候在 uiautomatorviewer 显示的界面也会横过来,我的解决办法是直接把 MuMu 设成类似手机的分别率

Ui Automator Viewer 增强
用 lazyuiautomatorviewer.jar 替代 Sdk\tools\lib 下的对应文件,这个 Viewer 可以显示元素的 xpath,注意换的时候名字记得改成和原来的一样

Appium 光速入门

from selenium.webdriver.common.by import By
from appium.webdriver.common.appiumby import AppiumBy
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import TimeoutException, NoSuchElementException
'''查找元素实例'''
element = driver.find_element(By.ID, 'com.tencent.mm:id/d5v')
# 会返回第一个找到的,如果没找到会抛出 NoSuchElementException 错误
# By.ID 是应该优先考虑的方法
element = driver.find_elements(By.CLASS_NAME, 'android.widget.LinearLayout')
# 返回所有符合元素的列表,如果没有符合的则返回空列表
driver.find_element(By.XPATH,"//android.support.v7.widget.RecyclerView[@resource-id='com.tencent.mm:id/a5u']/android.widget.LinearLayout[1]")
# By.XPATH 利用路径表达式查找元素
driver.find_elements(AppiumBy.ANDROID_UIAUTOMATOR, 'new UiSelector().text("'+text+'")')
# 利用元素的 text 属性查找元素
'''元素方法'''
element.click()
# 点击
element.send_keys()
# 输入
'''元素等待'''
def func(driver):return driver.find_elements(By.CLASS_NAME, 'android.widget.LinearLayout')
WebDriverWait(driver = mydriver, timeout = 1, poll_frequency = 0.5).until(func)
# 会在 timeout 时间内尝试调用 func(driver), 间隔 poll_frequency
# 当 func 返回真时提前退出
# 超时后抛出 TimeoutException 错误

完整代码

2022.01.31:还没写呢,今年的除夕都已经过了,明年再写吧

2022.02.01:还是给它写了,加了个自动登录的功能,因为模拟器和手机上切换登录时总是要输密码,于是就自动化了

import time
from typing import Listimport keyboard
from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy
from appium.webdriver.common.touch_action import TouchAction
from appium.webdriver.webdriver import WebDriver
from appium.webdriver.webelement import WebElement
from selenium.common.exceptions import (NoSuchElementException,StaleElementReferenceException,TimeoutException)
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWaitdef is_element_exist(driver, element, method='by_id', timeout=0, frequency=0.2):"""监听 element_text 是否在 timeout 时间内存在 , 结果以列表形式返回element_text: list 或 str 格式,当是 list 格式时表示是否存在其中任意一个可选method有: 'by_text', 'by_id'"""def exist(driver: WebDriver) -> List[WebElement]:if method == 'by_text':def find(text): return driver.find_elements(AppiumBy.ANDROID_UIAUTOMATOR, 'new UiSelector().text("'+text+'")')elif method == 'by_id':def find(id): return driver.find_elements(By.ID, id)else:raise ValueErrorif isinstance(element, str):return find(element)else:for ele in element:if find(ele):return find(ele)return []if timeout:try:WebDriverWait(driver, timeout, frequency).until(exist)except TimeoutException:return []else:return exist(driver)else:return exist(driver)class RedEnvelope():def __init__(self):self.desired_caps = {"platformName": "Android","deviceName": "pzyhfagmr8nfd6hm","platformVersion": "6.0.1","appPackage": "com.tencent.mm","appActivity": ".ui.LauncherUI","newCommandTimeout": 6000,"noReset": True}self.driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_capabilities=self.desired_caps)actions = TouchAction(self.driver)self.password = '不告诉你'self.grab_flag = Truedef login(self):# d5z:紧急冻结 cns:通讯录if not is_element_exist(self.driver, ['com.tencent.mm:id/d5z', 'com.tencent.mm:id/cns'], 'by_id', 10):print('微信启动失败')if is_element_exist(self.driver, 'com.tencent.mm:id/d5z'):print('检测到微信被登出,正在重新登录')# d5v:切换验证方式if is_element_exist(self.driver, 'com.tencent.mm:id/d5v'):self.driver.find_element(By.ID, 'com.tencent.mm:id/d5v').click()# f40:用xx登录[重复]if is_element_exist(self.driver, 'com.tencent.mm:id/f40', timeout=1):# 用密码登录self.driver.find_element(By.XPATH, "//android.support.v7.widget.RecyclerView[@resource-id='com.tencent.mm:id/a5u']/android.widget.LinearLayout[1]").click()self.login_with_password()else:print('等待用密码登录入口超时')else:print('登录微信成功 (由保持登录记录)')def login_with_password(self):print('正在用密码登录')if is_element_exist(self.driver, 'com.tencent.mm:id/bhn', timeout=1):self.driver.find_element(By.ID, 'com.tencent.mm:id/bhn').send_keys(self.password)self.driver.find_element(By.ID, 'com.tencent.mm:id/d5n').click()else:print('等待密码输入框超时')if is_element_exist(self.driver, ['com.tencent.mm:id/cns'], 'by_id', 10):print('登录微信成功 (由键入密码)')def main(self):print('正在启动微信')self.login()def add_hotkey_stop_grab(self):def stop_grab():self.grab_flag = Falsekeyboard.add_hotkey('ctrl+alt+r', stop_grab)print('激活了热键 ctrl+alt+r 以中止抢红包')def grab(self):# 如果要实现稳定多会话抢红包, 得再删除没有抢到的红包(不会显示消息:你已领取xx的红包)self.grab_from_message()return'''多会话'''# b4r 微信->每个会话窗口pers = is_element_exist(self.driver, 'com.tencent.mm:id/b4r')if pers:for per in pers:message = per.find_element(By.ID, 'com.tencent.mm:id/cyv').textif '[微信红包]' in message:per.click()self.grab_from_message()breakelse:self.grab_from_message()def grab_from_message(self):try:messages = is_element_exist(self.driver, 'com.tencent.mm:id/al7', timeout=1)for message in messages[::-1]:if is_element_exist(message, 'com.tencent.mm:id/ra'):# print('哇,发现一个红包!')env_app = is_element_exist(message, 'com.tencent.mm:id/r0')if env_app:pass'''气氛组'''# if env_app[0].text == '已领取':#     print('哦,是领过的')# elif env_app[0].text == '已被领完':#     print('啊,是没抢到的')# else:#     print('咦,这是什么')else:print('抢它!')message.click()# den:开bottom = is_element_exist(self.driver, 'com.tencent.mm:id/den', timeout=1, frequency=0.01)if bottom:bottom[0].click()# d_h 抢到xx元dh = is_element_exist(self.driver, 'com.tencent.mm:id/d_h', timeout=2, frequency=0.01)if dh:print('抢到 '+dh[0].text+' 元')else:print('没抢到')self.driver.find_element(By.ID, 'com.tencent.mm:id/dm').click()else:print('没抢到')# dem:红包下的xself.driver.find_element(By.ID, 'com.tencent.mm:id/dem').click()'''多会话'''# self.actions.long_press(message)# self.actions.perform()# self.driver.find_element(#     By.XPATH, "//android.widget.LinearLayout[@resource-id='com.tencent.mm:id/hyf']/android.widget.LinearLayout[1]").click()breakexcept StaleElementReferenceException:return'''多会话'''# rr:又上角的返回# rr = is_element_exist(#     self.driver, 'com.tencent.mm:id/rr', timeout=1)[0]# rr.click()def grab_start(self, frequcency=0):print('开始抢红包')self.add_hotkey_stop_grab()self.grab_flag = Truewhile self.grab_flag:self.grab()time.sleep(frequcency)print('抢红包中止')if __name__ == '__main__':R = RedEnvelope()R.main()# 建议用交互式# R.grab_start()

Append:Failed to create session

如果运行右下角 Start Session 后遇到一个报错

这里提到了原因:Default remote path should be “/wd/hub”
appium2 把 remote path 的默认设为/,此时最新版本的 Inspector 配合 appium2 也做了同步的更改,然而appium desktop 是面向新手的 GUI 版本,其内核迟迟没有更新到新的 appium2 ,解决这个问题简单的办法是下载旧版本的 Inspector,其中 2021.8.5 版本提到了这个修改

从0开始的appium+Android+python自动抢红包世界生活相关推荐

  1. python实现微信抢红包神器_快过年啦,还怕手速慢,我用Python自动抢红包!

    原标题:快过年啦,还怕手速慢,我用Python自动抢红包! 马上快过年啦,在春节的时间里,最少不了的就是大家在微信群里热热闹闹的发几个微信红包,图的就是一个喜庆. 今天,小编就带领大家用Python来 ...

  2. 简单的python抢红包脚本-Python自动抢红包,超详细教程,再也不会错过微信红包了!...

    来源:python专栏 github:https://github.com/MiracleYoung/You-are-Pythonista/tree/master/PythonExercise/Too ...

  3. Python自动抢红包,从此再也不会错过微信红包了!

    作者 | 上海小胖 来源 | Python专栏(ID:xpchuiit)  目录: 0 引言 1 环境 2 需求分析 3 前置准备 4 抢红包流程回顾 5 代码梳理 6 后记 0 引言 提到抢红包,就 ...

  4. 简单的python抢红包脚本-Python自动抢红包,超详细教程,再也不会错过微信红包了...

    0 引言 提到抢红包,就不得不提Xposed框架,它简直是个抢红包的神器,但使用Xposed框架有一个前提条件:手机需要root,对于苹果手机的话就需要越狱了.现在的手机想要root或越狱并不容易,同 ...

  5. python怎么自动抢红包软件_【一点资讯】超强大!教你用Python自动抢红包,再也不会错过任何一分钱...

    目录: 0 引言 1 环境 2 需求分析 3 前置准备 4 抢红包流程回顾 5 代码梳理 6 后记 0 引言 提到抢红包,就不得不提Xposed框架,它简直是个抢红包的神器,但使用Xposed框架有一 ...

  6. Python自动抢红包,超详细教程,再也不会错过微信红包了!

    目录: 0 引言 1 环境 2 需求分析 3 前置准备 4 抢红包流程回顾 5 代码梳理 6 后记 0 引言 提到抢红包,就不得不提Xposed框架,它简直是个抢红包的神器,但使用Xposed框架有一 ...

  7. 简单的python抢红包脚本-Python自动抢红包教程详解

    0 引言 提到抢红包,就不得不提Xposed框架,它简直是个抢红包的神器,但使用Xposed框架有一个前提条件:手机需要root,对于苹果手机的话就需要越狱了.现在的手机想要root或越狱并不容易,同 ...

  8. python自动抢红包软件_快过年啦,还怕手速慢,我用Python自动抢红包!

    话不多说,下面小编将从基础配置开始,让大家实现自动抢红包的功能. 1).下载并打开AirtestIDE编辑器. AirtestIDE编辑器采用的是压缩包的形式, 小编已经为大家下载好压缩包,大家只需要 ...

  9. 过年抢红包,还怕手速慢,我用Python自动抢红包!

    在春节的时间里,最少不了的就是大家在微信群里热热闹闹的发几个微信红包,图的就是一个喜庆. 今天,小编就带领大家用Python来制作一个自动抢红包的程序,不用动手就可以抢红,一起来看看吧. 01.准备工 ...

  10. python微信抢红包神器_快过年啦,还怕手速慢,我用Python自动抢红包!

    马上快过年啦,在春节的时间里,最少不了的就是大家在微信群里热热闹闹的发几个微信红包,图的就是一个喜庆. 今天,小编就带领大家用Python来制作一个自动抢红包的程序,不用动手就可以抢红,一起来看看吧. ...

最新文章

  1. 如何用计算机求锐角三角比,9.3用计算器求锐角三角比教学案
  2. WPF中的容器控件——Grid
  3. Ubuntu Server对OpenStack的支持
  4. 成功解决ModuleNotFoundError: No module named 'keras_retinanet'
  5. 【bzoj2460】[BeiJing2011]元素 贪心+高斯消元求线性基
  6. bootstraptable合并标题_Bootstrap-table 单元格合并 、表头合并
  7. python创建sqlite数据库表_python数据库sqlite基础(一)-------数据库创建,表的建立,数据录入,数据查询...
  8. jQuery Live Query 插件
  9. 本地虚拟机中匿名ftp上传文件失败的问题
  10. 代理服务器proxy server是什么?有什么作用
  11. iOS 让CoreData更简单些
  12. 函数发生器课程设计(Multisim仿真+PCB实物)
  13. 如何做一个基于微信驾校考试小程序系统毕业设计毕设作品
  14. 学期学会的一些代码23333原创
  15. springboot后端接受图片到本地
  16. “快播时代”终结:清内容、关服务器!
  17. 模拟10位QQ账号的生成
  18. 其他 | 狼人杀入门
  19. 用三个步骤实现响应式网页设计
  20. 记录mumu模拟器AMD SVM(VT)开启失败的问题

热门文章

  1. 软考高级信息系统项目管理师好考吗?
  2. angular8.x + ngx-translate实现国际化
  3. (八)RHEL系统之红帽8操作系统基础环境配置及软件安装
  4. 面试经验|华为二面分享 真难ε=(´ο`*)))唉
  5. 【二〇二〇·秋】读书笔记
  6. 基于YOLOv5的银行卡卡号识别(一)
  7. 世界著名的十大定律,你都知道吗
  8. 2020新版小桔灯作文能力阶梯序列作文课件教案教材全套
  9. 万有引力的意思_万有引力的本质是什么?
  10. NAIC2021-AI+视觉特征编码第一阶段开源方案