|
前言欢迎来到我的博客个人主页:北岭敲键盘的荒漠猫-CSDN博客本文是一个完成一个自动播放课程,避免人为频繁点击脚本的构思与源码。加油!为实现全部电脑自动化办公而奋斗!为实现摆烂躺平的人生而奋斗!!! 环境描述aibote,雷电模拟器,学习通,python3.12,pyaibote框架。环境不会搭建可以看我这篇博客:pyaibote--安卓自动化环境配置与基础的使用方法_aibote链接手机-CSDN博客成品代码fromPyAiboteimportAndroidBotMainimporttime#2.自定义一个脚本类,继承AndroidBotMainclassCustomAndroidScript(AndroidBotMain):#初始化配置Log_Level="DEBUG"Log_Storage=Truedefstart_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))defselect_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)ifself.my_classinresult:print("发现目标课程")result=self.find_text(self.my_class)print(result)self.click(result)time.sleep(1)deflook_class(self):#观看课程self.current_class=float(input("(示例:2.3)\n输入你当前刷课进度:"))#当前的课程self.show_first_class()whileTrue:self.cut_class()print("startlookclass")time.sleep(2)result=self.find_text("视频")print(result)self.click(result)time.sleep(3)self.ago_now()defago_now(self):#判断课程是否看过result=self.find_text("任务点已完成")ifresult==():result=self.get_element_rect("com.chaoxing.mobile/android.widget.Button@text=播放",5,0.5)self.click(result)time.sleep(3)#判断是否看完i=1whilei==1:time.sleep(5)outline=self.element_exists("com.chaoxing.mobile/android.widget.Button@text=重试",1,0.5)ifoutline:#判断是否断网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)ifresult:#判断是否看完self.back()time.sleep(2)result=self.find_text("任务点已完成")ifresult!=():breakelse:self.click_element("com.chaoxing.mobile/android.widget.Button@text=播放",1,0.5)self.back()defcut_class(self):#看完课程更替视频self.infor_dispose()whileTrue:#匹配课程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))ifresult==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))ifresult:#如果匹配到了进入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)ifresult:#转换章节后匹配到self.click_element("com.chaoxing.mobile/android.widget.TextView@text={}".format(self.current_class),5,0.5)self.current_class+=0.1#转换到下一门课breakelse:#匹配不到的话print("该课程已经刷完,或者程序出错。")breakdefshow_first_class(self):#防止第一个课程不在屏幕内result=self.element_exists("com.chaoxing.mobile/android.widget.TextView@text={}".format(self.current_class),5,0.5)ifresult:print("初始化目标课程在屏幕内")else:foriinrange(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)ifresult:breakdefinfor_dispose(self):#解决python浮点不精准问题self.current_class=round(self.current_class,2)self.current_class_1=self.current_class%0.1ifself.current_class_1==0:self.current_class=round(self.current_class,1)defscript_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类fromPyAiboteimportAndroidBotMainimporttime#2.自定义一个脚本类,继承AndroidBotMainclassCustomAndroidScript(AndroidBotMain):#2.1.设置是否终端打印输出DEBUG:输出,INFO:不输出,默认打印输出Log_Level="DEBUG"#2.2.终端打印信息是否存储LOG文件True:储存,False:不存储Log_Storage=True#2.3.注意:script_main此方法是脚本执行入口必须存在此方法defscript_main(self):#显示手机最近任务列表result=self.recent_tasks()print(result)if__name__=='__main__':#3.注意:此处监听的端口号,必须和手机端的脚本端口号一致#3.1监听16678号端口CustomAndroidScript.execute("0.0.0.0",16678)定义进入APP的方法我们需要通过找元素,点击进入这个区域。defstart_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))'运行运行通过这个方法来点进这个课程页面。定义选课方法我们需要找到我们想要的课程,于是我们定义这个方法来找课程。defselect_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)ifself.my_classinresult:#如果目标课程在里面就点击进入print("发现目标课程")result=self.find_text(self.my_class)print(result)self.click(result)time.sleep(1)'运行运行定义看课方法选好课程后我们总要开始刷课吧。这个方法是用来看课相关的操作的。deflook_class(self):#观看课程self.current_class=float(input("(示例:2.3)\n输入你当前刷课进度:"))#当前的课程self.show_first_class()#自定义的滑动函数(防止开始刷课的节数不在屏幕中)whileTrue:#循环执行self.cut_class()#自定义切换方法,用来判断当前应该看哪节课,并点进去print("startlookclass")time.sleep(2)#防止未加载出页面就文字识别导致错误result=self.find_text("视频")#识别文字print(result)self.click(result)#点击视频进去视频页面time.sleep(3)self.ago_now()#自定义函数,判断这节课是否刷完'运行运行定义滑动方法因为我们有可以自定义开始刷课节数的功能,那么我们可能会遇到这个节数不在屏幕中会下滑的情况,这个方法就是判断并且识别这种情况的。defshow_first_class(self):#防止第一个课程不在屏幕内result=self.element_exists("com.chaoxing.mobile/android.widget.TextView@text={}".format(self.current_class),5,0.5)ifresult:#判断屏幕中是否有这个课程的元素print("初始化目标课程在屏幕内")else:#如果没有foriinrange(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)ifresult:#如果该目标进入了屏幕就退出循环break'运行运行定义切换,判断当前课程是否刷完的方法第一我们要点进去这节课,第二我们还要根据他的元素text1.1这类的章节数,来找下一节课,最后我们计算机会有浮点计算偏差,但是课程就是1.1,2.2。最后的结果不能出现偏差,所以我们要把结果转化为正确无偏差的。defcut_class(self):#看完课程更替视频self.infor_dispose()#自定义方法解决计算机浮点计算偏差问题whileTrue:#匹配课程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))ifresult==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))ifresult:#如果匹配到了进入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)ifresult:#转换章节后匹配到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保留两位。definfor_dispose(self):#解决python浮点不精准问题self.current_class=round(self.current_class,2)self.current_class_1=self.current_class%0.1ifself.current_class_1==0:self.current_class=round(self.current_class,1)'运行运行定义判断这节该不该刷,以及刷完退出的方法我们肯定不能刷刷过的课浪费大量时间,这就需要我们加一个判定。循环前是进行判断,有没有那个任务点已完成。后面是刷课结束以及判断是否断网。defago_now(self):#判断课程是否看过result=self.find_text("任务点已完成")ifresult==():result=self.get_element_rect("com.chaoxing.mobile/android.widget.Button@text=播放",5,0.5)self.click(result)time.sleep(3)#判断是否看完i=1whilei==1:time.sleep(5)outline=self.element_exists("com.chaoxing.mobile/android.widget.Button@text=重试",1,0.5)ifoutline:#判断是否断网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)ifresult:#判断是否看完self.back()time.sleep(2)result=self.find_text("任务点已完成")ifresult!=():breakelse:self.click_element("com.chaoxing.mobile/android.widget.Button@text=播放",1,0.5)self.back()'运行运行最后组装方法在执行方法中拼凑方法。主要的方法是三大步骤。进入,选课,以及刷课defscript_main(self):#执行函数self.start_xuexitong()self.select_class()self.look_class()'运行运行总结以上就是整个刷课脚本的实现流程与代码,可以为我点一个赞吗。更新日志:5.3:ago_now方法存在逻辑漏洞,导致看课途中有概率会弹出。已修改。
|
|