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 = Truedef 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=1while 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!=():breakself.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  # 转换到下一门课breakelse: #如果不存在,下滑一下屏幕再匹配。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  # 转换到下一门课breakelse: #匹配不到可能是转换章节self.current_class+=1self.current_class-=(self.current_class%1)self.current_class+=0.1result = 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  # 转换到下一门课breakelse: #匹配不到的话print("该课程已经刷完,或者程序出错。")breakdef 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:breakdef infor_dispose(self):#解决python浮点不精准问题self.current_class=round(self.current_class,2)self.current_class_1=self.current_class%0.1if 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 AndroidBotMainimport time# 2. 自定义一个脚本类,继承 AndroidBotMainclass 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  # 转换到下一门课breakelse: #如果不存在,下滑一下屏幕再匹配。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  # 转换到下一门课breakelse: #匹配不到可能是转换章节self.current_class+=1self.current_class-=(self.current_class%1)self.current_class+=0.1result = 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  # 转换到下一门课breakelse: #匹配不到的话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.1if 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=1while 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!=():breakself.back()

最后组装方法

在执行方法中拼凑方法。

主要的方法是三大步骤。

进入,选课,以及刷课

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

总结

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

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux——socket套接字与udp通信

目录 一、理解IP地址与端口 二、socket套接字 三、TCP与UDP的关系 四、网络字节序 五、socket编程 1.socket()创建套接字 2.填充sockaddr_in 结构体 3.bind() 绑定信息 4.recvfrom()接收消息 5.sendto()发送消息 六、UdpServer代码 一、理解IP地址与端口 IP地址是In…

【C++】详解string类

目录 简介 框架 构造 全缺省构造函数 ​编辑 传对象构造函数 拷贝构造 析构函数 容量 size() capacity() empty() clear() reserve() ​编辑 resize() 遍历 检引用符号"[ ]"的重载 迭代器 begin() end() rbegin() rend(…

【触摸案例-控件不能响应的情况 Objective-C语言】

一、接下来,我们来说这个“控件不能响应的情况”, 1.素材里边,有一个“不接受用户交互的情况”,这么一个代码,把它打开, 把这个项目啊,复制过来,改一个名字,叫做“04-控件不能响应的情况”, 打开之后,command + R,运行一下, 在storyboard上,你也可以看得出来,我…

智慧农业设备——虫情监测系统

随着科技的不断进步和农业生产的日益现代化,智慧农业成为了新时代农业发展的重要方向。其中,虫情监测系统作为智慧农业的重要组成部分,正逐渐受到广大农户和农业专家的关注。 虫情监测系统是一种基于现代传感技术、图像识别技术和大数据分析技…

链表-----返回倒数第K个节点回文结构的判断相交链表

目录 1.返回倒数第K个节点 2.回文结构的判断 3.相交链表的判断,返回交点 1.返回倒数第K个节点 (1)返回链表的第k个节点,我们这里的做法是定义两个指针,这两个指针之间相差的是k这个长度;这个过程的实现就…

Android手势识别面试问题及回答

问题 1: 如何在Android中实现基本的手势识别? 答案: 在Android中,可以通过使用GestureDetector类来实现基本的手势识别。首先需要创建一个GestureDetector的实例,并实现GestureDetector.OnGestureListener接口来响应各种手势事件&#xff0c…

创建SpringBoot和RabbitMQ的整合项目

文章目录 创建SpringBoot和RabbitMQ的整合项目首先快速创建一个maven项目引入SpringBoot整合rabbitMQ的依赖在src/main目录下创建resources目录并引入配置文件写消息发送者MessageSender写消息接收者MessageReceiver写RabbitMQConfig配置类写SpringBoot启动主类CommandLineRunn…

小剧场短剧影视小程序源码_后端PHP

项目运行截图 源码贡献 https://githubs.xyz/boot?app42 部署说明 linux/win任选 PHP版本:7.3/7.2(测试时我用的7.2要安装sg扩展 ) 批量替换域名http://video.owoii.com更换为你的 批量替换域名http://120.79.77.163:1更换为你的 这两个…

代码随想录算法训练营第60天|84.柱状图中最大的矩形

84. 柱状图中最大的矩形 题目链接:柱状图中最大的矩形 题目描述:给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。 求在该柱状图中,能够勾勒出来的矩形的最大面积。 解题思路&#…

24 JavaScript学习:this

this在对象方法中 在 JavaScript 中,this 的值取决于函数被调用的方式。在对象方法中,this 引用的是调用该方法的对象。 让我们看一个简单的例子: const person {firstName: John,lastName: Doe,fullName: function() {return this.firstN…

【webrtc】MessageHandler 3: 基于线程的消息处理:以sctp测试为例

消息处理可以用于模拟发包处理G:\CDN\rtcCli\m98\src\net\dcsctp\socket\dcsctp_socket_network_test.cc 这个实现中,onMessage还是仅对了一种消息进行处理,就是接收则模式下,打印带宽。当然,可能程序有多个消息,分别在不同的onmessage中执行?SctpActor:以一个恒定的速率…

C语言贪吃蛇项目

今天给大家带来一款简单的贪吃蛇游戏,一起随我来看看吧 游戏效果: 实现基本的功能: • 贪吃蛇地图绘制 • 蛇吃⻝物的功能:(上、下、左、右⽅向键控制蛇的动作) • 蛇撞墙死亡 • 蛇撞⾃⾝死亡 • 计算得分…

Flink 实时数仓(一)【实时数仓离线数仓对比】

前言 昨天技术面的时候,面试官说人家公司现在用的都是最新的技术,比如 Doris 等一些最新的工具,确实这些课是学校永远不会开设的,好在他说去了会带着我做一做。可是 ...... 学院这边确实不允许放人,唉,可惜…

Kubernetes 弃用Docker后 Kubelet切换到Containerd

containerd 是一个高级容器运行时,又名 容器管理器。简单来说,它是一个守护进程,在单个主机上管理完整的容器生命周期:创建、启动、停止容器、拉取和存储镜像、配置挂载、网络等。 containerd 旨在轻松嵌入到更大的系统中。Docke…

python项目入门新手攻略

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

windows Jenkins运行python+selenium打开浏览器一直无响应,运行中,还没有打开浏览器

一开始解决办法是把打开服务把Jenkins给禁用了 但是没有用,然后找到安装目录 C:\Program Files\Jenkins 在这个路径下,在地址栏输入cmd打开命令窗口运行Jenkins启动命令 java -jar jenkins.war --httpPort8080 打开浏览器进入链接 http://localhost:…

【Unity学习笔记】第十四 Prefab 概念解惑

目录 1 prefab、prefab变体、prefab覆盖和prefab 嵌套2 connect 与unpack3 prefab到底是什么,它和gameobject又有什么区别?4 为什么要用prefab?5 代码动态加载prefab6 为什么我unity PrefabUtility.InstantiatePrefab() 得到的是null7 Prefab…

Redis基本命令

目录 一、包含String、Set数据类型的基本命令 1、添加一个键值对 2、获取key所关联的字符串值 3、同时设置多个key-value 4、获取多个key对应的值 运行结果 5、将给定的value追加到原值的末尾 追加后效果 6、删除单个key 7、同时删除多个key 8、查询包含某个字符的k…

ubuntu入门

基础命令 cd 切换命令 ls 查看当前目录下所有的文件 cp a.c b.c 拷贝a.c 到 b.c touch a.c 创建a.c文件 mkdir file 创建文件夹file rm file 删除文件 rmdir 删除test文件夹 rmdir test/ mv 移动文件 mv a.c b.c 把a.c 替换成b.c ifconfig 查看电脑网络信息 rm xx 删…

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…