赞
踩
前言
欢迎来到我的博客
个人主页:北岭敲键盘的荒漠猫-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=重试", 1, 0.5)
- if outline: #判断是否断网
- self.click_element("com.chaoxing.mobile/android.widget.Button@text=重试", 1, 0.5)
- result = self.element_exists("com.chaoxing.mobile/com.chaoxing.mobile:id=start", 1, 0.5)
- if result: #判断是否看完
- self.back()
- time.sleep(2)
- result=self.find_text("任务点已完成")
- if result!=():
- break
- else:
- self.click_element("com.chaoxing.mobile/android.widget.Button@text=播放", 1, 0.5)
- 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)
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
因为我已经刷完了,所以他点进去后,发现任务已完成就退出来进行下一节了。
他支持选择课程,定义开始课程节数,自动处理网络重连问题。
安卓自动化演示
我们先来分析一下学习通刷课的操作流程。
开启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)
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
我们需要通过找元素,点击进入这个区域。
- 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
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
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=重试", 1, 0.5)
- if outline: #判断是否断网
- self.click_element("com.chaoxing.mobile/android.widget.Button@text=重试", 1, 0.5)
- result = self.element_exists("com.chaoxing.mobile/com.chaoxing.mobile:id=start", 1, 0.5)
- if result: #判断是否看完
- self.back()
- time.sleep(2)
- result=self.find_text("任务点已完成")
- if result!=():
- break
- else:
- self.click_element("com.chaoxing.mobile/android.widget.Button@text=播放", 1, 0.5)
- self.back()
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
在执行方法中拼凑方法。
主要的方法是三大步骤。
进入,选课,以及刷课
- def script_main(self):
- #执行函数
- self.start_xuexitong()
- self.select_class()
- self.look_class()
以上就是整个刷课脚本的实现流程与代码,可以为我点一个赞吗。
更新日志:
5.3:ago_now方法存在逻辑漏洞,导致看课途中有概率会弹出。已修改。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。