栏目分类:
子分类:
返回
文库吧用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
文库吧 > IT > 软件开发 > 后端开发 > Python

uiautomator2+python+Android 自动化

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

uiautomator2+python+Android 自动化

为了减少人员的资源分配,减少可重复性检测的时间

提示:以下是本篇文章正文内容

1.引入库
import os
import time
import random
import datetime
import uiautomator2 as ut
2、检测连接手机(列表是用来做多线程执行…还未实现)
devices = []
# 检测是否连接手机
try:
    for dName_ in os.popen("adb devices"):
        if "t" in dName_:
            if dName_.find("emulator") < 0:
                devices.append(dName_.split("t")[0])
    devices.sort(cmp=None, key=None, reverse=False)
except:
    pass
3、报警提示(该位置使用的是飞书群机器人报警,也可以使用其他方式,例如:钉钉、邮件、短信)
    if devices == []:
        msg = 'Android手机 导致无法找到devices 进行启动Android自动化脚本。'
        send_FeiShu("无法连接", msg)
        exit()
4、录制case执行视频(直接用当前时间做视频名称,判断有没有video文件夹)
today = (datetime.datetime.now() - datetime.timedelta(days=0)).strftime('%Y_%m_%d_%H_%M_%S')
VideoName = f"case_{today}"
if not os.path.exists("video"):
    os.makedirs('video')
VideoPath = 'video'
device.screenrecord(VideoPath + "/" + VideoName + ".mp4")
5、查找应用(获取当前页面所有的文案,判断程序有没有在,没有就在下一屏找,直到找到并打开)
while True:
    device.press("home")
    device.press("home")
    text_list = [ele.text for ele in device.xpath('//android.widget.TextView').all()]
    if "XXX" not in text_list:
        device.swipe_ext('left', scale=0.9)
    else:
        device(text="XXX").click()
        time.sleep(5)
        try:
            device(resourceId="com.xxxxx.xxxxx:id/iv_dialog_active_close").click()
        except:
            print("不存在弹窗")
        break
6、text文档(编写执行case,格式如下)

例如:1、xx>xxx.xxxxx.xxxxx - xx>xxx.xxxxx.xxxxx
当中:“1、”、“>”、" - " 为解析使用

1、首页>com.xxxxx.xxxxx:id/button_bar_home_img - 直播电商>xxx.xxxxx.xxxxx:id/button_bar_streaming_img - 达人>xxx.xxxxx.xxxxx:id/button_bar_ranking_img - 社区>xxx.xxxxx.xxxxx:id/button_bar_commodity_img - 我的>xxx.xxxxx.xxxxx:id/button_bar_user_img
2、实时直播>xpath('//*[@resource-id="com.xxxxx.xxxxx:id/rlHomeFunction"]/android.view.ViewGroup[1]/android.widget.ImageView[1]') - 退出页面登录>com.xxxxx.xxxxx/ivPhoneLoginBack
3、我的>com.xxxxx.xxxxx:id/button_bar_user_img - 登录 - 首页>com.xxxxx.xxxxx:id/button_bar_home_img
4、直播引流>com.xxxxx.xxxxx:id/tv_live_business_live_drainage - 上滑(下滑)
7、解析case(读取case文档,进行解析)
# 读取文档,获取case
with open('ExecuteCodeAndroid.text', 'r', encoding='UTF-8') as code_find:
     # 解析case
     code_list = [code_i.split('、')[1].replace('n', '').split(' - ') for code_i in code_find.readlines()]
     for i in range(len(code_list)):
         for code_list_i in code_list[i]:
8、校验弹窗(获取当前页面所有文案,校验有没有关键词,有就进行指定点击)
# 获取当前页面文案,判断是否有弹窗
Tips = [elem.text for elem in device.xpath('//android.widget.TextView').all()]
if "个人信息保护指引" in Tips:
    device(resourceId="com.xxxxx.xxxxx:id/tv_dialog_agreement_confirm").click()
    device.swipe_ext("left", 0.6)
    device.swipe_ext("left", 0.6)
    device(resourceId="com.xxxxx.xxxxx:id/btn_item_welcome").click()
elif "好像哪里出错了" in Tips:
    device.xpath('//*[@text="返回"]').click()
elif "信息走失啦" in Tips:
    device.xpath('//*[@text="刷新"]').click()
elif "暂无数据" in Tips:
    device.xpath('//*[@text="稍后再试"]').click()
elif "访问过于频繁" in Tips:
    device.xpath('//*[@text="稍后再试"]').click()
elif "您当前账号登录" in Tips:
    device.xpath('//*[@text="取消"]').click()
9、执行(详细执行功能点击操作)
# 解析后长度大于等于 2 的时候
if len(code_list_i.split('>')) >= 2:
    if 'xpath' in code_list_i.split('>')[1]:
        device.xpath(f"""{code_list_i.split('>')[1].split("xpath('")[1].split("')")[0]}""").click()
    else:
        if ", text=" in code_list_i.split('>')[1]:
            resourceId_ = code_list_i.split('>')[1].split(', text=')[0]
            text_ = code_list_i.split('>')[1].split(', text=')[1].replace('"', '')
            device(resourceId=f"{resourceId_}", text=f"{text_}").click()
        else:
            if "text" in code_list_i.split(">")[1]:
                text_name = code_list_i.split(">")[1].split('(text="')[1].split('")')[0]
                device(text=f"{text_name}").click()
            else:
                device(resourceId=f"{code_list_i.split('>')[1]}").click()
# 小于 2
elif code_list_i.split('>')[0] == "登录":
    AndroidLogin()
elif code_list_i.split('>')[0] == "退出登录":
    AndroidLogout()
elif code_list_i.split(">")[0] == "输入":
    device(resourceId="com.xxxxx.xxxxx:id/etSearchEdit").set_text(InputGbk2312())
    device.send_action('search')
elif code_list_i.split('>')[0] == "上滑":
    Slide_up()
elif code_list_i.split('>')[0] == "下拉":
    Slide_down()
10、全部代码
import os
import time
import random
import datetime
import uiautomator2 as ut
from call_the_police import send_FeiShu # 飞书报警

while True:
    devices = []
    # 检测是否连接手机
    try:
        for dName_ in os.popen("adb devices"):
            if "t" in dName_:
                if dName_.find("emulator") < 0:
                    devices.append(dName_.split("t")[0])
        devices.sort(cmp=None, key=None, reverse=False)
    except:
        pass

    if devices == []:
        msg = 'Android手机 导致无法找到devices 进行启动Android自动化脚本。'
        send_FeiShu("无法连接", msg)
        exit()
    else:
        device = ut.connect_usb(devices[0])
        # 录制视频
        today = (datetime.datetime.now() - datetime.timedelta(days=0)).strftime('%Y_%m_%d_%H_%M_%S')
        VideoName = f"case_{today}"
        if not os.path.exists("video"):
            os.makedirs('video')
        VideoPath = 'video'
        device.screenrecord(VideoPath + "/" + VideoName + ".mp4")

        # 手机中查找 相关应用
        while True:
            device.press("home")
            device.press("home")
            text_list = [ele.text for ele in device.xpath('//android.widget.TextView').all()]
            if "抖查查" not in text_list:
                device.swipe_ext('left', scale=0.9)
            else:
                device(text="抖查查").click()
                time.sleep(5)
                try:
                    device(resourceId="com.xxxxx.xxxxx:id/iv_dialog_active_close").click()
                except:
                    print("不存在弹窗")
                break


        # 登录
        def AndroidLogin():
            try:
                device.xpath(
                    '//*[@resource-id="com.xxxxx.xxxxx:id/ll_user_top"]/android.widget.LinearLayout[1]/android.widget.LinearLayout[1]').click()
            except:
                print('非"我的"页面进行登录')
            device(text="密码登录").click()
            device(resourceId="com.xxxxx.xxxxx:id/cb").click()
            device(text="请输入手机号").set_text("18730301074")
            device(text="请输入密码").set_text("ceshi123")
            device(text="登录").click()


        # 退出登录
        def AndroidLogout():
            device(resourceId="com.xxxxx.xxxxx:id/tv_user_setting").click()
            device(resourceId="com.xxxxx.xxxxx:id/btnLogout").click()
            device(resourceId="com.xxxxx.xxxxx:id/tv_logout_confirm").click()


        # 随机输入 1 个字
        def InputGbk2312():
            head = random.randint(0xb0, 0xf7)
            body = random.randint(0xa1, 0xfe)
            val = f'{head:x}{body:x}'
            str = bytes.fromhex(val).decode('gb2312')
            return str


        # 上滑
        def Slide_up():
            device.swipe_ext("up", 0.6)


        # 下拉
        def Slide_down():
            device.swipe_ext("down", 0.6)


        # 读取文档,获取case
        with open('ExecuteCodeAndroid.text', 'r', encoding='UTF-8') as code_find:
            # 解析case
            code_list = [code_i.split('、')[1].replace('n', '').split(' - ') for code_i in code_find.readlines()]
            for i in range(len(code_list)):
                for code_list_i in code_list[i]:
                    # 获取当前页面文案,判断是否有弹窗
                    Tips = [elem.text for elem in device.xpath('//android.widget.TextView').all()]
                    if "个人信息保护指引" in Tips:
                        device(resourceId="com.xxxxx.xxxxx:id/tv_dialog_agreement_confirm").click()
                        device.swipe_ext("left", 0.6)
                        device.swipe_ext("left", 0.6)
                        device(resourceId="com.xxxxx.xxxxx:id/btn_item_welcome").click()
                    elif "好像哪里出错了" in Tips:
                        device.xpath('//*[@text="返回"]').click()
                    elif "信息走失啦" in Tips:
                        device.xpath('//*[@text="刷新"]').click()
                    elif "暂无数据" in Tips:
                        device.xpath('//*[@text="稍后再试"]').click()
                    elif "访问过于频繁" in Tips:
                        device.xpath('//*[@text="稍后再试"]').click()
                    elif "您当前账号登录" in Tips:
                        device.xpath('//*[@text="取消"]').click()
                    # 解析后长度大于等于 2 的时候
                    if len(code_list_i.split('>')) >= 2:
                        if 'xpath' in code_list_i.split('>')[1]:
                            device.xpath(f"""{code_list_i.split('>')[1].split("xpath('")[1].split("')")[0]}""").click()
                        else:
                            if ", text=" in code_list_i.split('>')[1]:
                                resourceId_ = code_list_i.split('>')[1].split(', text=')[0]
                                text_ = code_list_i.split('>')[1].split(', text=')[1].replace('"', '')
                                device(resourceId=f"{resourceId_}", text=f"{text_}").click()
                            else:
                                if "text" in code_list_i.split(">")[1]:
                                    text_name = code_list_i.split(">")[1].split('(text="')[1].split('")')[0]
                                    device(text=f"{text_name}").click()
                                else:
                                    device(resourceId=f"{code_list_i.split('>')[1]}").click()
                    # 小于 2
                    elif code_list_i.split('>')[0] == "登录":
                        AndroidLogin()
                    elif code_list_i.split('>')[0] == "退出登录":
                        AndroidLogout()
                    elif code_list_i.split(">")[0] == "输入":
                        device(resourceId="com.xxxxx.xxxxx:id/etSearchEdit").set_text(InputGbk2312())
                        device.send_action('search')
                    elif code_list_i.split('>')[0] == "上滑":
                        Slide_up()
                    elif code_list_i.split('>')[0] == "下拉":
                        Slide_down()

                #     list_data = [elem.text for elem in device.xpath('//android.widget.TextView').all()]
                # if "暂无相关数据" in list_data:
                #     msg = f"case: {i + 1}"
                #     send_FeiShu("无数据", msg)  # 增加钉钉或飞书报警
        # 结束录制
        device.screenrecord.stop()
    break

总结

例如:以上就是今天要讲的内容,本文仅仅只是对于uiautomator2+Android+python的使用,而uiautomator2依旧有很多待发现的内容,等待我们发现。

近期会将ios的自动化同步到此,敬请期待哦!

转载请注明:文章转载自 www.wk8.com.cn
本文地址:https://www.wk8.com.cn/it/1037422.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 wk8.com.cn

ICP备案号:晋ICP备2021003244-6号