Loading

Appium自动化操作手机端软件-Damai-Ticket-Grab-Tutorial-2024

一、缘起

有很多朋友来找我弄演唱会的票,于是来看看。

大麦网站不允许在Web端进行购买,这意味着之前的那种Selenium的方式应该是无法操作了。

Github上找到了一个项目,是支持小程序抢票的,这是一个新的领域,我们开始学习学习。

大麦App抢票:大麦App抢票

Appium手机自动化的原理:Appium原理与安装

二、先说说环境

看了App部分的Readme,依赖的软件有Node环境,NpmAndroid SdkAppiumUiAutomator2驱动。

为了做到稍微的知其然知其所以然,我还是想先看看这些东西的作用,而不是无脑的安装。

因为今天在打Pikachu靶场的时候遇到了目录遍历,需要用Dirbuster这个工具,想起来之前写的一篇非常详细的工具说明,看完那叫一个清晰明朗,给了我用心做技术博客一些鼓励。

image-20241011102053744

1、Node环境

摘自node.js官网的解释。

# Run JavaScript Everywhere

Node.js® is a free, open-source, cross-platform JavaScript runtime environment that lets developers create servers, web apps, command line tools and scripts.

Node.js®是一个免费、开源、跨平台的JavaScript运行时环境,允许开发人员创建服务器、web应用程序、命令行工具和脚本。

这里有一些名词,我们暂时不对免费,开源,跨平台这些简单名词进行解释。

好吧还是解释一下,免费就是不要钱,开源就是开放源代码,就像大家分享在Github上的抢票脚本,你是可以看到脚本的运行逻辑的,源码可下载可修改。还有一些软件是闭源的,会把代码实现的逻辑隐藏起来。

参考这个网站的一段解释来说明什么是开源:开源指南

“开源”是什么意思?
当一个项目被开源,这意味着任何人都可以出于任何目的查看,使用,修改和分发你的项目。 这些权限通过开源许可强制实施。

开源是强大的,因为它降低了事物被采纳的障碍,使得我们的想法可以被迅速传播。

接下来我们通过一个例子了解它的工作原理。想象你的朋友组织了一场聚餐,而你带去了一个樱桃派。

每个人都尝了那个派(使用)
派的味道棒极了!大家请你分享它的配方(view)
一个叫 Alex 的朋友是个糕点师,他建议少放点糖(modify)
一个叫 Lisa 的朋友想要用它作为下周的晚餐(distribute)
相比之下,一个闭源过程就像去一家餐厅订购一个樱桃派。你必须为了吃饼支付费用,餐厅恐怕不会给你他们的食谱。如果你准确地复制了他们的馅饼,并以你自己的名义出售,餐厅可以对你采取措施。

跨平台指的是它可以在不同系统(WindowsLinuxMacOs)不同架构(x86x64)上运行。而不用为每个平台都编写一个不同的代码。

Javascript是一门编程语言,多用于前端,和htmlcss并称前端三剑客,而node.js就是来运行Javascript的一个环境。当然,Javascript还可以运行在浏览器端,当我们用F12打开开发者工具时就能够在浏览器的控制台运行Javascript

那为什么需要一个Node呢?Node是用来在服务器端运行Javascript的,这样开发者可以不用学习常规的PhpJsp,同样可以编写后端(服务端)的代码,而是只需要在服务器上安装Node.js环境即可,这对于我们来说是方便的。如果世界上有一种语言又快又好,那么大家都不用学JavaPython或者其他乱起八糟的了,可是事实却不是这样...

关于Node的介绍:Node

ReadMe中要求Node的版本是18.0.0,这里只在官网找到18.20.4的版本。

Node18.20.4:预编译安装包下载页

那么Node.js包含了NpmNpm又是什么鬼?

2、Npm包管理?

NpmNode.js 的标准包管理器。

Npm简介:Npm包管理

什么是包,什么又是包管理?

假设我要做一个蛋糕,我需要去沃尔玛里面买相关的食材,比如牛奶,鸡蛋,面粉等等。

我当然可以自己养一头牛自己生产牛奶,自己再养一只鸡自己弄鸡蛋。但是没必要,超市里已经有,我直接拿来用不就很好吗?

假设我现在要开发一个抢票软件,需要识别图片验证码登录,我当然也可以自己写,但是在世界的某个角落,肯定有人已经写好了这个功能,那么他就会将这些代码打包(假设他打包之后命名为pic_read)上传到相关的包管理器的仓库中,我只需要去仓库里下载他写好的这个包,就可以使用图片验证码的这个功能了。

所以,对于我的抢票软件来说,pic_read就是我这个程序的依赖软件,想要运行我的程序,就必须要下载这个依赖才行。

关于Linux的包管理:什么是包管理器?

什么是Pip和Npm包管理器:Npm和Pip

Node.Js中已经集成了Npm包管理,因为我们的抢票脚本很可能也需要利用网上面别人写好的代码包,所以Npm就能够为我们提供一个很好的下载平台。

顺便提一句,Npm的性质类似于PythonPip,这一点在上面分享的文章中也有讲述。

在这里我们使用Npm包是为了安装一个名为Appium的东西,这又是啥?

3、Appiuim

我就喜欢这种把官网做的赏心悦目的工程组,是我们学习的好榜样啊。

Appiuim官方网站:Appium

从官网简短的描述中我们可以知道,Appium是一个实现Ui自动化的生态系统,那么同学又要问了,什么是Ui自动化?

欢迎来到 Appium 文档!Appium 是一个开源项目和相关软件的生态系统,旨在促进许多应用程序平台的 UI 自动化,包括移动(iOS、Android、Tizen)、浏览器(Chrome、Firefox、Safari)、桌面(macOS、Windows)、电视(Roku、tvOS、Android TV、三星)等!

正如主页上提到的,Appium 旨在支持许多不同平台(移动、Web、桌面等)的 UI 自动化。不仅如此,它还旨在支持以不同语言(JS、Java、Python 等)编写的自动化代码。将所有这些功能组合到一个程序中是一项非常艰巨的任务,如果不是不可能的话!

Ui也就是(User Interface),可以简单理解为我们的图形化界面这些东西,我们使用的Windows系统,浏览器,App都是Ui的产物。

与之对应的是命令行界面,就是我们可以通过敲代码来完成日常的所有操作,在Linux系统上用的比较多。

Ui的好处就是所见即所得,用户不需要学习复杂的代码操作,就可以为新建一个文档,为其重命名。但是它的缺点就是无法直接编写代码操作这些Ui软件,于是就出现了Ui自动化,它能够以代码的形式定位Ui元素,实现自动化操作。就像我们的抢票脚本一样。

Web也就是浏览器端,我使用Selenium+Js来进行Ui自动化(看官网简介好像Appium也可以用来进行WebUi自动化),它可以通过判断页面的Dom元素来完成按钮点击,文字输入这些操作。

但是在手机上的App端,就需要用到Appium这样的生态系统了。

什么是Ui自动化:Ui自动化简介

Appium是如何工作的,在简单理解了其官网文章之后,给出一点看法。

appium是一个运行在node.js上的服务器,它本身不提供自动化操作android手机或者ios手机的功能。

它通过安装对应的驱动程序来实现对应平台上的ui自动化,比如想在ios上做自动化,安装XCUITest,想在android手机上实现自动化,安装UiAutomator2

于是,一个运行在Node.js环境下,并且带有UiAutomator2驱动的Appium服务就启动起来了,它应该是一个http服务,之类的,这个服务器需要连接到你想要执行自动化操作的设备上,所有的自动化操作都由这个服务器来执行。

正如它提到的,它支持用不同语言(JS、Java、Python 等)编写自动化代码,对于我这种只会Python的人来说简直太好了,于是我们下载Appium的客户端,在上面用Python(或者任何你会的语言)编写好自动化程序的执行脚本,然后将指令发送给服务器,服务器在你想执行自动化操作的设备上执行之后,将结果再返回给客户端。

理解了Appium的工作原理,我们再来看看Android sdk,这是什么东西,我猜测是因为我们需要在Android设备上执行自动化操作,所以需要安装这个东东。

关于Appium的详细介绍:Appium的详细介绍

4、Android Sdk

简单说就是Android Software Development Kit,安卓软件开发套件。

其中的AdbAndroid Debugging Bridge调试桥接套件,可以让我们在Pc端控制安卓手机,记得之前在小程序抓包的时候也有用到过这个,反正用电脑自动化操作手机大概都要下载Sdk

由于Android是基于Java开发的,所以使用Sdk需要先安装JavaJdkJava Development Kit)。

关于什么是Android Sdk:Android Sdk

5、UiAutomator2

最后再来说说这个在Android手机上实现自动化的框架。

关于什么是Ui Automator2,摘抄自网络,侵删。

UI Automator 是 Google 提供的测试框架,允许您自动与 Android 应用程序的用户界面进行交互。它对于测试涉及多个应用之间交互的方案特别有用。在我们的例子中,我们将使用它来测试两个 Android 应用程序之间的交互。

其实我们可以直接使用UiAutomator来进行安卓手机的自动化操作,但遗憾的是UiAutomator2只支持Java语言,所以我们使用Appium+Uiautomator2的方式来用Python语言运行自动化代码。

在查询过程中还发现有大神使用Python来驱动UiAutomator2的:深度探索 Uiautomator2(ATX)原理(附含源码解析)

关于Appium和UiAutomator之间的关系:自动化测试框架对比(UIAutomator、Appium)

6、安装环境

铺垫的知识学的差不多了,来安装把。

(一)、Node.Js

Node.Js:Node.Js18.20.4

Node.Js安装教程:2024Node.Js安装

(二)、Android-Sdk

Android-Sdk不是一个软件,而是包含了很多开发工具的软件包,需要安装Sdk管理工具,然后下载对应的Sdk软件包。

image-20241012091345583

现如今安装Android-Sdk,有两种方式,一种是下载Android Studio使用其中的Sdk管理器来下载。

另外一种只需要下载Sdkmanager就可以了,于是我选第二种。

Sdkmanager下载地址:Windows-Sdk

下载完成后解压需要将文件夹目录改成这样,不然的话会报一个版本错误。

┌ android-sdk
│    ├ cmdline-tools
│    │     ├ latest
│    │     │     ├ bin
│    │     │     ├ lib
│    │     │     ├ NOTICE.txt
│    │     │     ├ source.properties

image-20241012092711473

之后按照下面文章中的方法下载"platform-tools" "platforms;android-30" "build-tools;30.0.3"这几个软件,还有模拟器和镜像啥的,下载好之后这些工具就会出现再Android-Sdk这个目录下,不然原本只会有cmdline-tools

使用Android Sdkmanager安装Android Sdk:在不安装Studio的情况下安装Sdk

然后再按照这个文章配置环境变量。

什么是环境变量:Linux环境变量解析

配置Sdk环境变量:Sdk环境变量配置

image-20241012092255983

image-20241012092131879

Path环境变量配置。

image-20241012092354632

配置好之后应该可以随意打开一个cmd使用adbAndroid Debug Bridge)软件,用于Pc端和安卓手机端之间的调试

image-20241012092458485

其他参考文章...

另一篇使用Android Sdkmanager安装Android Sdk:使用Sdkmanager安装Sdk

不是写给初学者看的:官网对Sdkmanager的介绍

(三)、Npm安装Appium

然后通过npm下载,一开始记得换上国内的镜像源。不然下载会很慢。

什么是镜像源?就好像长沙有茶颜悦色,但是你跑长沙买就很慢,于是在你家小区楼下也开了一家一摸一样的,这样就快了。

Npm的默认软件仓库是在国外的服务器上的,国人下载很不方便,于是一些大公司就把这个仓库复制一份到国内来,于是就有了阿里源,腾讯源之类的,这些东东在国内的服务器上,方便我们的下载。

Npm镜像源配置:Npm镜像源

然后按照安装Appium,并且为其配置环境变量。

给Appium配置环境变量:Npm安装Appium

好像又不用配置环境变量,直接安装就行,但是我在Powershell环境下和Cmd环境下运行同样的命令结果却不同。

npm install -g appium #安装Appium

appium -v #查看安装是否成功

image-20241012104448558

(四)、安装Uiautomator2

  appium driver install uiautomator2 #安装Uiautomator2
  
  appium driver list #检查是否成功安装

image-20241012104749719

(五)、Appium-Python-Client

Pycharm中安装Appium-Python-Client是非常简单的,不懂可以自己查查,就不细讲了。

image-20241012110754321

(六)、特别声明

我发现使用模拟器来操作会无法购票,会不停的让你做滑动验证码,可能是服务器识别到了某些特征,暂时我们先不管它。

解决方式是使用真机,打开开发者模式,以及Usb调试。

三、看看代码

环境大差不差的准备好了,接下来下载了代码看看怎么运行。

这个代码里面没有交代怎么运行和配置App端的东东。

我摸索了一下大概是这样。

1、让代码先跑起来

首先要下载一个安卓模拟器(当然你也可以用真实机),然后开启开发者模式,在Pc端打开命令行,输入AdbAndroid Debug Bridge,之前安装Android Sdk的时候下载好了的,已经配置到环境变量中的了。)

我下载的是Mumu模拟器,由于在虚拟机里面使用,一开始提示了没有开启VtVirtual Technology),我们需要在虚拟机设置中勾选一下,如果是物理机一般不需要弄,我的主板上默认是开了的。

image-20241012210437899

现在我需要在Mumu的多开器上看一下模拟器使用的端口号,然后使用Adb连接上安卓模拟器,确保Pc端和手机端是可以联通的。

image-20241012210651958

顺便开启一下模拟器的Root模式,不知道会不会影响我们的操作。

image-20241012211724832

然后打开命令行提示窗口,使用adb来连接上我们的安卓模拟器。

image-20241012211237112

然后在Appium运行一下,会看到Appium_Server运行在4723端口,这个好像是默认的。

image-20241012213408181

Config文件中配置一下。

image-20241012213528759

之后就可以运行一下damai_app脚本,记得需要在模拟器上安装大麦App软件。

大概运行起来的样子是这样,还有很多Bug要自己改改,比如在面临弹窗的时候会识别不到元素之类种种。

image-20241012214115924

2、看看代码如何运行

我们看到报错的信息。

首先是说没有找到这个元素,但是,如何在App上面定位元素啊?我不知道啊?

image-20241012214530906

没关系,大哥我爱学,查。

(一)、如何在App定位元素

(1)、Uiautomator

上网查查人家说用Android Sdk中自带的小工具Uiautomator来定位。

image-20241013095409930

我试着打开一下,发现Java版本不匹配,人家说要下Jdk1.8的版本才能用这个工具。

image-20241013094911224

于是去Oracle官网安装一下。

Jdk1.8:下载地址

image-20241013093740629

由于我不想改环境变量,太麻烦了,一会换一个版本的,我上网找到了一种方法在Bat脚本的开头为它设置我Jdk1.8的文件位置,这样运行这个脚本时就会配置一个临时的Java环境。

rem Set Jdk to 1.8
set JAVA_HOME=C:\Program Files (x86)\Java\jdk-1.8
set java_exe="%JAVA_HOME%"/bin/java.exe

image-20241013095332328

保存后,再打开就可以了。

由于我们已经连接上了Adb,它可以自动识别到模拟器上的手机屏幕,并且获得对应的元素节点。

image-20241013104955006

当我们切换界面后,要重新点击小按钮来刷新元素的获取。

Uiautomator View使用教程:View使用教程

(2)、Uiautomator-魔改版

这个原生的小工具有一个缺点,无法定位xpath,我在Github上找了一个魔改版。

可定位Xpath的Uiautomatorview:github地址

安装的教程在网址上有。奶奶滴,安装之后发现这个魔改版本根本不好用,避雷!很多App界面它是无法识别到控件的(原生的Viewer有些也会出现这个问题,但是是可解决的,通过打开手机开发者模式或者重启AdbAppiumViewer之类的,感兴趣自己查)。

image-20241013143558273

(3)、Appium Inspector(好用啊!)

于是咱们又找到了一个靠谱的软件,Appium Inspector,这个是官方开发的,还不错。

下载地址:Appium Inspector

安装教程:Appium Inspector

需要添加的配置单元。

{
  "platformName": "Android",
  "appium:automationName": "UiAutomator2"
}

image-20241014092018730

image-20241013143234031

(二)、检查代码逻辑

(1)、加载配置文件-Config.py

开篇第一行代码,这个Conifg是从config.py文件中导入的,它是用来加载抢票相关配置信息,以及appium的连接配置信息的。

# 加载配置信息
config = Config.load_config()

image-20241013150441341

Json格式的配置文件。

image-20241013150540953

(2)、设置Appium的启动参数

各个参数的详细说明文档:Appium官方

官方的根本不会看,看这篇吧:各个参数解释

[一]、获取安卓版本

在手机上的设置--关于手机里一般有。

image-20241013152448885

[二]、设备名称

这一栏不用修改,随便填,对于安卓系统来说目前没用。

image-20241013152651489

[三]、获取包名

查看app的包名,在Pc端输入下列命令,然后打开对应的App,比如说大麦,就会出现包名啦。

adb shell am monitor

image-20241013152158409

[四]、设置Activity

查了很多资料,不太理解appactivity的作用,像是说作为判断软件从不同入口进入的依据,比如是从桌面打开的软件,又或者是从别的页面跳转过来的,以此依据展示不同的界面?

询问Ai后它说我的想法是对的,它说当从通知栏,浏览器,桌面,这些不同地方打开同一个软件时,该软件的反应是不一样的,那么标识该软件从哪里打开,有没有开机动画之类的,就是Activity来标识。

我们在这随便填应该也不影响,我发现在AppiumInspector中可以看到当前的Activity

比如我先切换到设置在切换回大麦。

image-20241013204516464

和我从主屏幕打开大麦。

image-20241013204553396

(3)、连接Appium Server

接下来Python Client需要连接Appium Server给它发指令了

driver = webdriver.Remote(config.server_url, options=device_app_info)

(4)、定位元素

历经千辛万苦,终于来到定位元素的时候了。如何定位元素前面也说了,用Appium Inspector这个软件。

image-20241014092506589

它这的代码逻辑很简单,就是不断的去找各个控件,点击,下一步这样。

关键在于识别控件的快慢,还有异常的处理。

下面是逻辑大概的讲解。

image-20241014093343536

image-20241014093422512

以上所有的实现都是通过识别控件的Xpath,然后发送点击,或者输入文字,来完成。

现在还有关键的问题,就是等待时间的优化,由于网络延迟的问题,每个控件的加载并不一定非常快,这时候元素还没加载出来,我们就使用find_Element来寻找元素的话会出现找不到元素,然后报错的情况。

所以为了避免这种情况,Selenium提供一些等待的方式。脚本中默认使用的是隐式等待,为了加快脚本的速度,我还想寻找更好的方式。

并且其中的一些代码逻辑做的也不太完善,我们来丰富一下

(三)、脚本优化

在网络上看了一个论坛,给出了一些方案。

主流有三种

1、appium模拟人操作

2、Hook技术

3、分析App发送的请求,逆向其加密的参数,重放请求

23种都需要很多时间重新学习,我暂时没有拌饭实现。

于是又看了一看如何优化Appium的执行速度。

感觉没有什么可优化的,这个技术栈的天花板比较矮。

然后我想要判断按钮上的文字,但是没有找到获取元素的文本。

image-20241014130956480

这个脚本优化暂时还没有什么办法做,就先告一段落吧。

Else、备忘录

1、Chocolatey

目标:了解Chocolatey,使用其来安装一个环境。

安装Node.js时勾选了一个chocolatey,简单查了一下是一个Windows的包管理器,类似于debian上的aptred hat上的rpm,它使用Powershell来安装软件,自动配置环境变量,非常方便。

参考文章:用Chocolate安装Java

2、Powershell

之前一直在用命令行执行,新系统上Powershell似乎更强大。

目标:了解Powershell能做些什么。

posted @ 2024-10-14 13:19  南瓜薯仔  阅读(5120)  评论(2)    收藏  举报