python安卓自动化pyaibote实践------学习通自动刷课

前言

欢迎来到我的博客

个人主页:北岭敲键盘的荒漠猫-CSDN博客

本文是一个完成一个自动播放课程,避免人为频繁点击脚本的构思与源码。

加油!为实现全部电脑自动化办公而奋斗!

为实现摆烂躺平的人生而奋斗!!!

 环境描述

aibote,雷电模拟器,学习通,python3.12,pyaibote框架。

环境不会搭建可以看我这篇博客:pyaibote--安卓自动化环境配置与基础的使用方法_aibote链接手机-CSDN博客

成品代码

from PyAibote import AndroidBotMain
import time

# 2. 自定义一个脚本类,继承 AndroidBotMain
class CustomAndroidScript(AndroidBotMain):
    #初始化配置
    Log_Level = "DEBUG"
    Log_Storage = True
    def start_xuexitong(self):
        #打开学习通,进入看课区域
        result = self.start_app("学习通", 5, 0.5)
        print("app运行状态:{}".format(result))
        place=self.get_element_rect("com.chaoxing.mobile/com.chaoxing.mobile:id=tabButton[3]", 15, 0.5)
        self.click((place))
        print("点击任务状态:{}".format(place))
        place=self.get_element_rect("com.chaoxing.mobile/com.chaoxing.mobile:id=myCourse", 15, 0.5)
        self.click((place))
        print("点击任务状态:{}".format(place))

    def select_class(self):
        #选择目标课程,并且判断是否有课程
        self.my_class=input("输入想要刷课的名称:")
        result = self.init_ocr_server("127.0.0.1", False, False, False)
        print("初始化状态:{}".format(result))
        result = self.get_text()
        print(result)
        if self.my_class in result:
            print("发现目标课程")
            result = self.find_text(self.my_class)
            print(result)
            self.click(result)
            time.sleep(1)

    def look_class(self):
        #观看课程
        self.current_class=float(input("(示例:2.3)\n输入你当前刷课进度:")) #当前的课程
        self.show_first_class()
        while True:
            self.cut_class()
            print("start look class")
            time.sleep(2)
            result = self.find_text("视频")
            print(result)
            self.click(result)
            time.sleep(3)
            self.ago_now()

    def ago_now(self):
        #判断课程是否看过
        result=self.find_text("任务点已完成")
        if result==():
            result = self.get_element_rect("com.chaoxing.mobile/android.widget.Button@text=播放", 5, 0.5)
            self.click(result)
            time.sleep(3)
            #判断是否看完
            i=1
            while i==1:
                time.sleep(5)
                outline=self.element_exists("com.chaoxing.mobile/android.widget.Button@text=重试", 2, 0.5)
                if outline: #判断是否断网
                    self.click_element("com.chaoxing.mobile/android.widget.Button@text=重试", 2, 0.5)
                result = self.get_element_rect("com.chaoxing.mobile/com.chaoxing.mobile:id=start", 2, 0.5)
                if result!=(): #判断是否看完
                    self.click_element("com.chaoxing.mobile/com.chaoxing.mobile:id=back", 5, 0.5)
                time.sleep(2)
                result=self.find_text("任务点已完成")
                if result!=():
                    break
        self.back()

    def cut_class(self):
        #看完课程更替视频
        self.infor_dispose()
        while True:
            #匹配课程
            print(self.current_class)
            result = self.element_exists("com.chaoxing.mobile/android.widget.TextView@text={}".format(self.current_class), 5, 0.5)
            print("当前课程的状态:{}".format(result))
            if result==True: #如果存在课程,就点击进入课程
                result=self.click_element("com.chaoxing.mobile/android.widget.TextView@text={}".format(self.current_class), 5, 0.5)
                self.current_class += 0.1  # 转换到下一门课
                break
            else: #如果不存在,下滑一下屏幕再匹配。
                print("屏幕未找到对应元素,正在执行下滑操作")
                self.swipe((306, 1116), (306, 750), 1)
                result = self.element_exists(
                    "com.chaoxing.mobile/android.widget.TextView@text={:.1f}".format(self.current_class), 5, 0.5)
                print("下滑后匹配元素状态:{}".format(result))
                if result: #如果匹配到了进入
                    self.click_element(
                        "com.chaoxing.mobile/android.widget.TextView@text={:.1f}".format(self.current_class), 5, 0.5)
                    self.current_class += 0.1  # 转换到下一门课
                    break
                else: #匹配不到可能是转换章节
                    self.current_class+=1
                    self.current_class-=(self.current_class%1)
                    self.current_class+=0.1
                    result = self.element_exists(
                        "com.chaoxing.mobile/android.widget.TextView@text={}".format(self.current_class), 5, 0.5)
                    if result: #转换章节后匹配到
                        self.click_element(
                            "com.chaoxing.mobile/android.widget.TextView@text={}".format(self.current_class), 5,
                            0.5)
                        self.current_class += 0.1  # 转换到下一门课
                        break
                    else: #匹配不到的话
                        print("该课程已经刷完,或者程序出错。")
                        break

    def show_first_class(self):
        #防止第一个课程不在屏幕内
        result = self.element_exists(
            "com.chaoxing.mobile/android.widget.TextView@text={}".format(self.current_class), 5, 0.5)
        if result:
            print("初始化目标课程在屏幕内")
        else:
            for i in range(15):
                self.swipe((402, 1404), (402, 564), 2)
                result = self.element_exists(
                    "com.chaoxing.mobile/android.widget.TextView@text={}".format(self.current_class), 3, 0.5)
                if result:
                    break

    def infor_dispose(self):
        #解决python浮点不精准问题
        self.current_class=round(self.current_class,2)
        self.current_class_1=self.current_class%0.1
        if self.current_class_1==0:
            self.current_class=round(self.current_class,1)

    def script_main(self):
        #执行函数
        self.start_xuexitong()
        self.select_class()
        self.look_class()


if __name__ == '__main__':
    CustomAndroidScript.execute("0.0.0.0", 16678)

效果演示

因为我已经刷完了,所以他点进去后,发现任务已完成就退出来进行下一节了。

他支持选择课程,定义开始课程节数,自动处理网络重连问题。

安卓自动化演示

需求操作分析

我们先来分析一下学习通刷课的操作流程。

开启APP

点击我,点击课程,然后从里面选取要刷的课。

选好课程后,我们需要选择我们要从哪节开始刷。

点进去后要点击视频切换到视频的页面

之后我们要判断这节有没有刷,刷完返回下一节,没刷就进去看。

如果看的话,还要判断好是否结束了。还要应对中途可能发生的网络异常情况。

识别到看完后,我们就要返回进入下一节以此类推

代码解刨

基本框架

首先是pyaibote的基本运行框架。

我们把要执行的代码放到script_main中。

  # 1. 导入 AndroidBotMain 类
  from PyAibote import AndroidBotMain
  import time
  
  
  
  # 2. 自定义一个脚本类,继承 AndroidBotMain
  class CustomAndroidScript(AndroidBotMain):
  
      # 2.1. 设置是否终端打印输出 DEBUG:输出, INFO:不输出, 默认打印输出
      Log_Level = "DEBUG" 
  
      # 2.2. 终端打印信息是否存储LOG文件 True: 储存, False:不存储
      Log_Storage = True  
  
  
      # 2.3. 注意:script_main 此方法是脚本执行入口必须存在此方法
      def script_main(self):
          # 显示手机最近任务列表
          result = self.recent_tasks()
          print(result)
  
  
  
  
  
  
  
  
  if __name__ == '__main__':
      # 3. 注意:此处监听的端口号,必须和手机端的脚本端口号一致
      # 3.1 监听 16678 号端口
      CustomAndroidScript.execute("0.0.0.0", 16678)

定义进入APP的方法

我们需要通过找元素,点击进入这个区域。

    def start_xuexitong(self):
        #打开学习通,进入看课区域
        result = self.start_app("学习通", 5, 0.5)
        print("app运行状态:{}".format(result))
        place=self.get_element_rect("com.chaoxing.mobile/com.chaoxing.mobile:id=tabButton[3]", 15, 0.5)
        self.click((place))
        print("点击任务状态:{}".format(place))
        place=self.get_element_rect("com.chaoxing.mobile/com.chaoxing.mobile:id=myCourse", 15, 0.5)
        self.click((place))
        print("点击任务状态:{}".format(place))

通过这个方法来点进这个课程页面。

定义选课方法

我们需要找到我们想要的课程,于是我们定义这个方法来找课程。

    def select_class(self):
        #选择目标课程,并且判断是否有课程
        self.my_class=input("输入想要刷课的名称:")
        #初始化文字识别服务
        result = self.init_ocr_server("127.0.0.1", False, False, False)
        print("初始化状态:{}".format(result))
        #查找文本
        result = self.get_text()
        print(result)
        if self.my_class in result:#如果目标课程在里面就点击进入
            print("发现目标课程")
            result = self.find_text(self.my_class)
            print(result)
            self.click(result)
            time.sleep(1)

定义看课方法

选好课程后我们总要开始刷课吧。

这个方法是用来看课相关的操作的。

    def look_class(self):
        #观看课程
        self.current_class=float(input("(示例:2.3)\n输入你当前刷课进度:")) #当前的课程
        self.show_first_class() #自定义的滑动函数(防止开始刷课的节数不在屏幕中)
        while True: #循环执行
            self.cut_class() #自定义切换方法,用来判断当前应该看哪节课,并点进去
            print("start look class")
            time.sleep(2) #防止未加载出页面就文字识别导致错误
            result = self.find_text("视频")#识别文字
            print(result)
            self.click(result) #点击视频进去视频页面
            time.sleep(3)
            self.ago_now() #自定义函数,判断这节课是否刷完

定义滑动方法

因为我们有可以自定义开始刷课节数的功能,那么我们可能会遇到这个节数不在屏幕中会下滑的情况,这个方法就是判断并且识别这种情况的。

    def show_first_class(self):
        #防止第一个课程不在屏幕内
        result = self.element_exists(
            "com.chaoxing.mobile/android.widget.TextView@text={}".format(self.current_class), 5, 0.5)
        if result: #判断屏幕中是否有这个课程的元素
            print("初始化目标课程在屏幕内")
        else: #如果没有
            for i in range(15): #下拉寻找
                self.swipe((402, 1404), (402, 564), 2)
                result = self.element_exists(
                    "com.chaoxing.mobile/android.widget.TextView@text={}".format(self.current_class), 3, 0.5)
                if result: #如果该目标进入了屏幕就退出循环
                    break

定义切换,判断当前课程是否刷完的方法

第一我们要点进去这节课,

第二我们还要根据他的元素text1.1这类的章节数,来找下一节课,

最后我们计算机会有浮点计算偏差,但是课程就是1.1,2.2。最后的结果不能出现偏差,所以我们要把结果转化为正确无偏差的。

    def cut_class(self):
        #看完课程更替视频
        self.infor_dispose() #自定义方法解决计算机浮点计算偏差问题
        while True:
            #匹配课程
            print(self.current_class)
            result = self.element_exists("com.chaoxing.mobile/android.widget.TextView@text={}".format(self.current_class), 5, 0.5)
            print("当前课程的状态:{}".format(result))
            if result==True: #如果存在课程,就点击进入课程
                result=self.click_element("com.chaoxing.mobile/android.widget.TextView@text={}".format(self.current_class), 5, 0.5)
                self.current_class += 0.1  # 转换到下一门课
                break
            else: #如果不存在,下滑一下屏幕再匹配。
                print("屏幕未找到对应元素,正在执行下滑操作")
                self.swipe((306, 1116), (306, 750), 1)
                result = self.element_exists(
                    "com.chaoxing.mobile/android.widget.TextView@text={:.1f}".format(self.current_class), 5, 0.5)
                print("下滑后匹配元素状态:{}".format(result))
                if result: #如果匹配到了进入
                    self.click_element(
                        "com.chaoxing.mobile/android.widget.TextView@text={:.1f}".format(self.current_class), 5, 0.5)
                    self.current_class += 0.1  # 转换到下一门课
                    break
                else: #匹配不到可能是转换章节
                    self.current_class+=1
                    self.current_class-=(self.current_class%1)
                    self.current_class+=0.1
                    result = self.element_exists(
                        "com.chaoxing.mobile/android.widget.TextView@text={}".format(self.current_class), 5, 0.5)
                    if result: #转换章节后匹配到
                        self.click_element(
                            "com.chaoxing.mobile/android.widget.TextView@text={}".format(self.current_class), 5,
                            0.5)
                        self.current_class += 0.1  # 转换到下一门课
                        break
                    else: #匹配不到的话
                        print("该课程已经刷完,或者程序出错。")
                        break

定义去除偏差方法

python浮点数加减其实会有一个很小偏差。

比如1.1+0.1=1.2000000002。

但是我们下一节就是1.2这样会出错。

于是我们用下面方法来四舍五入到我们规定的格式。

保留两位小数,如果利用取余判断小数第二位是否为0。

为0保留一位,不为0保留两位。

    def infor_dispose(self):
        #解决python浮点不精准问题
        self.current_class=round(self.current_class,2)
        self.current_class_1=self.current_class%0.1
        if self.current_class_1==0:
            self.current_class=round(self.current_class,1)

定义判断这节该不该刷,以及刷完退出的方法

我们肯定不能刷刷过的课浪费大量时间,这就需要我们加一个判定。

循环前是进行判断,有没有那个任务点已完成。

后面是刷课结束以及判断是否断网。

    def ago_now(self):
        #判断课程是否看过
        result=self.find_text("任务点已完成")
        if result==():
            result = self.get_element_rect("com.chaoxing.mobile/android.widget.Button@text=播放", 5, 0.5)
            self.click(result)
            time.sleep(3)
            #判断是否看完
            i=1
            while i==1:
                time.sleep(5)
                outline=self.element_exists("com.chaoxing.mobile/android.widget.Button@text=重试", 2, 0.5)
                if outline: #判断是否断网
                    self.click_element("com.chaoxing.mobile/android.widget.Button@text=重试", 2, 0.5)
                result = self.get_element_rect("com.chaoxing.mobile/com.chaoxing.mobile:id=start", 2, 0.5)
                if result!=(): #判断是否看完
                    self.click_element("com.chaoxing.mobile/com.chaoxing.mobile:id=back", 5, 0.5)
                time.sleep(2)
                result=self.find_text("任务点已完成")
                if result!=():
                    break
        self.back()

最后组装方法

在执行方法中拼凑方法。

主要的方法是三大步骤。

进入,选课,以及刷课

    def script_main(self):
        #执行函数
        self.start_xuexitong()
        self.select_class()
        self.look_class()

总结

以上就是整个刷课脚本的实现流程与代码,可以为我点一个赞吗。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/587022.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python项目入门新手攻略

最近工作需要接手了代码量比较大的python开发的项目,平时写python不多,记录一下如何熟悉项目。 分析调用流程-pycallgraph 因为代码量比较大,所以希望通过工具生成代码调用流程,因此用到了pycallgraph。 pycallgraph&#xff0…

翻译: 什么是ChatGPT 通过图形化的方式来理解 Transformer 架构 深度学习三

合集 ChatGPT 通过图形化的方式来理解 Transformer 架构 翻译: 什么是ChatGPT 通过图形化的方式来理解 Transformer 架构 深度学习一翻译: 什么是ChatGPT 通过图形化的方式来理解 Transformer 架构 深度学习二翻译: 什么是ChatGPT 通过图形化的方式来理解 Transformer 架构 深…

56.基于SSM实现的在线教育网站系统(项目 + 论文)

项目介绍 本站是一个B/S模式系统,采用Java的SSM框架作为开发技术,MYSQL数据库设计开发,充分保证系统的稳定性。系统具有界面清晰、操作简单,功能齐全的特点,使得基于SSM的在线教育网站的设计与实现管理工作系统化、规范…

Scikit-Learn回归树

Scikit-Learn回归树 1、决策树1.1、什么是决策树1.2、决策树学习的步骤1.3、决策树算法 1、决策树 决策树(DTs)是一种用于回归和分类的有监督学习方法。通常,决策树用于分类问题;当决策树用于回归问题时,称为回归树。回…

Midjourney之绘画背景的选择

hello 小伙伴们,我是你们的老朋友——树下,今天分享Midjourney提示词中绘画背景的选择,话不多说,直接开始~ 对于背景的选择,Midjourney中主要体现在年代和所处的环境对绘画产生不同的影响 科技的发展,我们…

matlab学习006-使用matlab绘出系统的冲激响应和阶跃响应波形并求其冲激响应的数值解

目录 题目 1,绘出系统的冲激响应和阶跃响应波形 1)基础 2)效果 3)代码 2,求出t0.5s,1s,1.5s,2s时系统冲激响应的数值解。 1)基础 2)效果 ​☀ 3)代码 题目 已知描述某连续系…

【Python】Anaconda 使用笔记

文章目录 一、创建环境1.1 在任意磁盘中创建环境1.2 添加环境路径envs_dirs 二、安装和使用Python环境三、删除已有的Python环境 前言   笔者使用Python的目的主要是为了学习神经网络等深度学习算法。但是在学习之初配置环境的时候发现之前的环境配置一团乱麻,不仅…

Mybatis进阶(动态SQL)

文章目录 1.动态SQL1.基本介绍1.为什么需要动态SQL2.基本说明3.动态SQL常用标签 2.环境搭建1.新建子模块2.删除不必要的两个文件夹3.创建基本结构4.父模块的pom.xml5.jdbc.properties6.mybatis-config.xml7.MyBatisUtils.java8.MonsterMapper.java9.MonsterMapper.xml10.测试Mo…

第七篇:专家级指南:Python异常处理的艺术与策略

专家级指南:Python异常处理的艺术与策略 1 引言 在编程的世界中,异常处理是一门必修的艺术。它不仅涉及到程序的错误处理,更广泛地影响着软件的稳定性、健壮性和用户体验。本篇文章将深入探讨Python中的异常处理,展示如何通过精心…

Linux:服务器间同步文件的脚本(实用)

一、功能描述 比如有三台服务器,hadoop102、hadoop103、hadoop104,且都有atguigu账号 循环复制文件到所有节点的相同目录下,且脚本可以在任何路径下使用 二、脚本实现 1、查看环境变量 echo $PATH2、进入/home/atguigu/bin目录 在该目录下…

三. Django项目之电商购物商城 -- 校验用户名 , 数据入库

Django项目之电商购物商城 – 校验用户名 , 数据入库 需要开发文档和前端资料的可私聊 一. 路由匹配获得用户名 在注册时 , 用户输入用户名 , 通过ajax请求发送到服务器 , 在路由中设置对应url , 响应视图 , 将用户输入的用户名传入视图 , 与数据库进行校验检查用户名是否重…

信息技术内涵及意义

一、信息技术及其演进趋势 (一)信息技术概况概念 信息技术(Information Technology,IT)指“应用在信息加工和处理中的科学、技术与工程的训练方法与管理技巧;上述方法和技巧的应用;计算机及其…

linux高性能服务器--Ngix内存池简单实现

文章目录 内存模型:流程图内存对齐code 内存模型: 流程图 内存对齐 对齐计算 要分配一个以指定大小对齐的内存,可以使用如下公式: 假设要分配大小为n,对齐方式为x,那么 size(n(x-1)) & (~(x-1))。 举个…

【大模型系列】大模型的上下文长度解释与拓展

文章目录 1 什么是大模型的上下文长度?2 拓展大模型上下文长度的方式参考资料 1 什么是大模型的上下文长度? 大模型的上下文长度(Context Length)是指在自然语言处理(NLP)的大型语言模型(Large…

自动的异地组网工具?

越来越多的企业和个人对远程访问和异地组网需求日益增加。为了满足这一需求,各种技术和服务也不断涌现。其中一项备受关注的技术就是自动的异地组网。本文将介绍这一技术的优势和特点。 【天联】组网的优势 天联组网技术以其卓越的性能和稳定性备受用户称赞。它的优…

数据结构:实验七:数据查找

一、 实验目的 (1)领会各种查找算法的过程和算法设计。 (2)掌握查找算法解决实际问题。 二、 实验要求 (1)编写一个程序exp8-1.cpp, 按提示输入10个任意的整形数据(无序)&…

数字旅游引领未来智慧之旅:科技应用深度重塑旅游生态,智慧服务全面升级打造极致高品质旅游体验

随着信息技术的飞速发展,数字旅游作为旅游业与科技融合的新兴业态,正以其独特的魅力和优势,引领着旅游业迈向智慧之旅的新时代。数字旅游不仅通过科技应用重塑了旅游生态,更通过智慧服务为游客带来了高品质的旅游体验。本文将深入…

从键入网址到网页显示,期间发生了什么?

从键入网址到网页显示,期间发生了什么? 孤单小弟【HTTP】真实地址查询【DNS】指南帮手【协议栈】可靠传输【TCP】远程定位【IP】两点传输【MAC】出口【网卡】送别者【交换机】出境大门【路由器】互相扒皮【服务器与客户端】相关问答 不少小伙伴在面试过程…

浅谈Agent AI智能体的未来

Agent AI智能体的未来非常广阔和潜力巨大。随着技术的发展和应用场景的不断拓展,我们可以期待以下几个方面的发展: 更加智能化:Agent AI智能体将会变得越来越智能,具备更强大的学习、推理和决策能力。它们可以通过大数据和机器学习…

java序列化和反序列化基础学习

一、前言 前文分析了java的反序列化的DNSURL利用链,但是对于java反序列化的一些过程不是很了解,这篇主要记录下学习java反序列基础知识 二、原理 概念 1、什么是序列化和反序列化 (1)Java序列化是指把Java对象转换为字节序列…