提醒,本期不仅需要Python基础,还得理解面向对象和懂多线程 。请酌情观看 。
一、不同需求的难度差别
薅羊毛脚本,就是想用程序来做重复动作 。这个重复,有简单有复杂,不同需求下,问题难度差别很大 。我们从简单到复杂 。
1、简单版
最基本的就是下滑 。这个很容易编写 。一个无限循环搞定 。
while True:
sleep(2)
下滑
2、升级版
如果想隔20分钟去做任务,然后程序运行到足够时间停止呢 。这个也比较容易 。
while True:
时间判断:
执行任务 or 退出循环
sleep(2)
下滑
3、挑战版
如果想多App运行足够时间后自动切换,同样也隔20分钟做任务呢?是不是觉得难度一下子提升好多,完全两码事了?
有句话说,0到1是最困难的 。编程也适用 。编程里0代表是1,1则是2 。编程,单任务,顺序执行,很简单 。一旦变成2个,就困难 。而再进一步2变更多,又容易 。
在薅羊毛脚本中,上面的问题是核心,大部分代码都围绕它展开 。而解决它,使用面向过程编程和单线程就不容易 。需要用面向对象和多线程 。
二、我的解决思路
1、封装
面向对象的三大特征是封装、继承和多态 。而封装最基本,将不同业务逻辑用类来包装 。
App动作和执行分离
脚本中apps.py下有多个App名称的类 。比如JingDong,封装了京某的业务:签到、逛商品,逛活动、看视频和其他 。而JingDongMain则是执行的类 。
封装基础工具
MyAuto类封装了u2的各种功能,比如点击、下滑等 。
调度类
AutoMain类里面包含程序的入口start,还封装了控制逻辑和保存数据的逻辑 。
多线程执行 。
网上有些片面言论,比如Python有GIL锁,多线程没用,做不到真正的并行和并发 。好像Python的多线程一无是处,不值得学习和使用 。在薅羊毛脚本中,将业务执行和调度放在不同的线程里,才能控制程序运行 。
这样来比喻 。采用面向对象和多线程,就如同当老板雇人来干活,但员工都不太聪明,只会干一件事 。在薅羊毛里 。员工A只会下滑和做任务,需要给他工具,还得告诉它什么时候下滑和做任务 。员工B记录时间,让他来告诉员工A该干啥 。一个人(单线程)搞不定?不行,他笨只能干一件事,不能边干边记录时间 。那让员工聪明点自带工具行不行 。他不干活了,我们都不知道是工具坏了还是他偷懒(隔离方便维护代码) 。
2、线程间传递信息(通信)
如何告诉业务循环该干啥了呢?这就得解决线程通信的问题 。线程间通信有多种方法 。可以用全局变量和Queue,而我采用的是传入字典的方式 。Python一切都是对象 。字典是可变类型的对象 。对象可以作为参数传入函数或类,所以可以用来传递信息 。
我的脚本中有一个核心调度字典,task_control 。它创建于AtuoMain,作为参数传入TaskThread,又作为参数传入App的Main函数,再作为参数传入watch_content的无线循环浏览中 。机制是这样的 。当切换任务条件出现后,就会修改task_control,而无线循环中会一直读取task_control,来完成信息传递 。(更高级的线程安全问题,这里就不讨论了 。)
3、如何切换任务
脚本中长时间浏览都是无限循环,信息传递进去了,如何跳出循环来切换任务呢?我用的是抛异常 。Python异常传递是层层传递,直到被捕获 。它可以穿透命名空间 。我利用这种机制来切换任务 。所以脚本中定义了多个异常类 。这些都是为切换任务而设 。因为脚本里有大量的循环,采用return的方法比较麻烦,所以采用了这种方式 。
三、总结
针对开始的问题:多App运行足够时间后自动切换,中间执行任务的问题 。我是用一个线程执行动作,一个线程负责调度 。通过字典来传递信息,抛出异常来切换任务 。朋友们有更好的方法,欢迎交流探讨 。也希望使用脚本的朋友 。
文章插图
【python如何写脚本 python自动薅羊毛】
秒懂生活扩展阅读
- 宝宝的新水杯第一次怎么清洗 宝宝的新水杯第一次如何清洗
- 夏季如何预防蚊子
- 委托书怎么写?个人委托个人范本
- 高中语文名句默写
- 如何用废布做马桶垫
- 如何彻底清洗海参
- 开题报告中的国内外研究现状怎么写?
- 忙着做事不得空闲写一个词语
- 描写哀的成语
- 如何关掉所有正在运行的程序