加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

如何用Python投机倒把几天“暴富”!Python暴富就是简单!

发布时间:2020-12-17 00:40:21 所属栏目:Python 来源:网络整理
导读:本文涉及到的技术点有(多图预警!): 1.? Packet Capture和Charles抓包 ?; 2.? 安卓AccessibilityService无障碍服务实现自动下注 ?; 3.? Python爬虫模拟下注 ?; 4.? Python Flask编写简单接口 ?; 行吧,别做梦了,暴富了,我还这里码字?标题党的感觉

本文涉及到的技术点有(多图预警!):

  • 1.?Packet Capture和Charles抓包?;
  • 2.?安卓AccessibilityService无障碍服务实现自动下注?;
  • 3.?Python爬虫模拟下注?;
  • 4.?Python Flask编写简单接口?;

行吧,别做梦了,暴富了,我还这里码字?标题党的感觉就是舒服,还是踏踏实实搬砖吧!关于赚大钱的捷径都写在刑法里,想具体了解的可以到逼乎自行查阅:?都说最赚钱的方法都在刑法里面,那么宪法里面到底禁止了哪些暴利的赚钱方法?这些方法到底有多赚钱呢??我只能帮你们到这里了。投机倒把暴富的念想是挺美好的,但我投机倒把的真实的结果是:?国庆短短几天,因为投机倒把我亏了7755块?(截止目前亏了?9073块?)...

进群:548377875? 即可获取你想不到的学习资料哦!

编写本文的出于下面几个初衷:

  • 1.记录自己在投机倒把过程中运用到的一些?开发技术?;
  • 2.记录这次投机倒把的经历,以此警示自己以后要踏踏实实做事;
  • 3.奉劝各位有这种念想的伙计?引以为戒?,?远离投机倒把?,?保持身心健康?。

在真正开始本文之前,要严肃的强调几点:

  • 投机倒把?,十有九??,或者十??,??!投机倒把中赚钱的永远是极少数的幸运儿。如果只为?娱乐?,?不为赢钱?可以,参考过年家里常有的小赌怡情,玩个几百块,赢了和输了都收手。
  • 本文不是让你去投机倒把,所以不会提供任何APP下载外链或文件!

本文的讲解流程:

先讲解一波投机倒把相关的概念,然后通过和两个好基友的沙雕聊天记录,引出一些开发相关的东西,分析一波投机倒把过程里的一些猫腻,希望各位看官会喜欢这个有(??)趣(??)的真实故事~

第零章:名词碎碎念

先来了解一波和投机倒把有关的名词吧~

0.1 赌徒心理(贪欲和侥幸心理)

赢了还想赢更多的钱,输了又想回本,反复告诉自己赢一把就收手,回本就收手,事实上,只有当自己的前输得精光的时候才会收手。

举个例子:

  • 1.下注,输了10块,想着把10块赚回来,又压了10块,然后又输,又压20,再输压30...本没有回,钱却越输越多。
  • 2.输了10块,下把下注奖为5块,?赢了?,?患得患失?,如果刚刚那把压多一点就赢好多了,?输了?,?暗自庆幸?,幸好把下注少了,不然就亏大了。

赢钱的时候也不会见好就收,毕竟对于赌徒来说,收手是最难的。

0.2 大数法则

大数不是?大叔?,又称“?平均法则?”,即:?在随机事件的大量重复中往往出现几乎必然的规律?。在实验条件不变的情况下,重复实验多次,随机事件的频率近似于它的概率。举个例子,我们都知道的常识:?抛硬币?,正反面的概率各占50%。但是,现在让你去抛两次硬币,却很难出现刚好一正一反的情况。只在你重复了上千上万次后,正和反出现的次数接近持平。

看到这里,读者可能有这样的疑问:

既然最后是五五开,那我一直玩,为什么?最后还是亏了?,难道是有?中间商?赚差价了?

讲真,真的有?中间商?,尽管从概率上来说,是五五开的,但是有两点根本不平等。

首先,概率是建立在?大量重复实验?的基础上的,庄家有“用不完的钱”,可以进行无限次投机倒把,且没有赌徒心理,而反观赌徒的资金一般是有限的。然后呢,又有一个名词,概率波动论。

0.3 概率波动论

具备两面性的规律从概率来讲是对半的,但在一段时间内有可能多数呈一面性表现。举个简单的三个骰子买大小的例子(1-9小,10-18大),10次的结果是这样的(连续3次大):

概率波动是概率发生的必然,因此投机倒把过程中可能出现连续输好几把的情况。

0.4 倍投法

接着是中间商赚差价的第二点,比如有一些买大小单双的赌局,胜率并不是?1:2?,比如?1:1.96,或者?1:1.82?等,比如你一把玩1块,第一把输了,第二把也投1块,你中了,只赢?1.96?块,但是,其实你已经花了?2块钱?,亏4分钱。如果是1.86的,亏1毛4,看上去数额很少是吧,但是基本都不会只玩几把吧,一天下来可能玩了上千把,一个赌客就贡献了好几百,赌客肯定不止你一个,而且下注也肯定不会1块1块的来,所以说说为什么那么多投机倒把类的APP。而扭转这种亏损的一种简单而且赚钱的做法,就是倍投法。举个简单的例子,假如赔率是1:2的话,下注的金额是这样一个列表:?[10,20,40,80,160,320,640,1280,2560...]?,第一把投10块,输了,第2把投20,赢了40,减去本金30,赚10,没中,第3把投40,赢了80,减去本金70,赚10块,就是保证每一轮赢10块。我们写个简单的Python代码来生成一个倍投收益的表格。代码如下(?prettytable库用于生成表格):

from prettytable import PrettyTable
purchase_base = 10 # 购买基数
ratio = 2 # 中奖倍率
price_list = [] # 投入金额
def init_purchase_list():
 x = PrettyTable(['投入','投入总额','获利','净利润'])
 cost = 0
 price_list.append(purchase_base)
 # 其他进行动态计算
 print("初始化投入金额表格...")
 for i in range(0,10):
 cost += purchase_base * (2 ** i) # 花费
 bonus = purchase_base * (2 ** i) * ratio # 奖金
 x.add_row([purchase_base * (2 ** i),cost,bonus,bonus - cost])
 print(x)
if __name__ == '__main__':
 init_purchase_list()

运行下程序,可以得出一个倍投的结果列表:

初始化投入金额表格...
+------+----------+-------+--------+
| 投入 | 投入总额 | 获利 | 净利润 |
+------+----------+-------+--------+
| 10 | 10 | 20 | 10 |
| 20 | 30 | 40 | 10 |
| 40 | 70 | 80 | 10 |
| 80 | 150 | 160 | 10 |
| 160 | 310 | 320 | 10 |
| 320 | 630 | 640 | 10 |
| 640 | 1270 | 1280 | 10 |
| 1280 | 2550 | 2560 | 10 |
| 2560 | 5110 | 5120 | 10 |
| 5120 | 10230 | 10240 | 10 |
+------+----------+-------+--------+

每一轮才挣10块,有点少是吧,你可以试试赚更多的3倍投,把上面的代码改一下:

for i in range(0,10):
 cost += purchase_base * (3 ** i) # 花费
 bonus = purchase_base * (3 ** i) * ratio # 奖金
 x.add_row([purchase_base * (3 ** i),bonus - cost])

输出结果如下:

初始化投入金额表格...
+--------+----------+--------+--------+
| 投入 | 投入总额 | 获利 | 净利润 |
+--------+----------+--------+--------+
| 10 | 10 | 20 | 10 |
| 30 | 40 | 60 | 20 |
| 90 | 130 | 180 | 50 |
| 270 | 400 | 540 | 140 |
| 810 | 1210 | 1620 | 410 |
| 2430 | 3640 | 4860 | 1220 |
| 7290 | 10930 | 14580 | 3650 |
| 21870 | 32800 | 43740 | 10940 |
| 65610 | 98410 | 131220 | 32810 |
| 196830 | 295240 | 393660 | 98420 |
+--------+----------+--------+--------+

卧槽,刺激是吧,如果有30W的本金,三倍投,不中的次数越多,你赚的钱越多。如果连续不中到10次,中了,一轮1将近10W,这种是敢死队倍投法,很难很难挂一次,但是一旦出现一次直接跌入18层地狱永不超生!(笔者试过好几次...等下细讲)。这种是平台比例1:2的情况,有些中间商赚差价的平台的赔率是1.96这样,上面的代码生成的结果就变成了(2倍投,ratio改为1.96):

初始化投入金额表格...
+------+----------+---------+---------------------+
| 投入 | 投入总额 | 获利 | 净利润 |
+------+----------+---------+---------------------+
| 10 | 10 | 19.6 | 9.600000000000001 |
| 20 | 30 | 39.2 | 9.200000000000003 |
| 40 | 70 | 78.4 | 8.400000000000006 |
| 80 | 150 | 156.8 | 6.800000000000011 |
| 160 | 310 | 313.6 | 3.6000000000000227 |
| 320 | 630 | 627.2 | -2.7999999999999545 |
| 640 | 1270 | 1254.4 | -15.599999999999909 |
| 1280 | 2550 | 2508.8 | -41.19999999999982 |
| 2560 | 5110 | 5017.6 | -92.39999999999964 |
| 5120 | 10230 | 10035.2 | -194.79999999999927 |
+------+----------+---------+---------------------+

是的,普通的二倍投法越到后面反而越亏,而三倍投依旧是赚钱的,在本金不够充裕无法三倍投的情况下,要在二倍投的基础上加点,而且少于三倍投,保证我们每把赚的钱>购买基数,而且投入的金额最少,我们改下下我们的代码:

from prettytable import PrettyTable
purchase_base = 10 # 购买基数
ratio = 1.96 # 中奖倍率
price_list = [] # 投入金额
def init_purchase_list():
 x = PrettyTable(['投入','净利润'])
 x.add_row([purchase_base,purchase_base,round(purchase_base * ratio,2),round(purchase_base * ratio - purchase_base,2)])
 cost = purchase_base
 price_list.append(purchase_base)
 # 其他进行动态计算
 print("初始化投入金额表格...")
 for i in range(10):
 purchase = 0
 # 购买价格其实区间(2倍)
 start_price = purchase_base * (2 ** i)
 # 购买价格极限区间(3倍)
 end_price = purchase_base * (3 ** i)
 # 保证没把不亏就行
 for j in range(start_price,end_price + 1):
 if j * ratio - cost - j > purchase_base:
 x.add_row([j,cost + j,round(j * ratio,round(j * ratio - cost - j,2)])
 cost += j
 price_list.append(j)
 break
 print(x)
if __name__ == '__main__':
 init_purchase_list()

输出下注金额列表如下:

初始化投入金额表格...
+------+----------+----------+--------+
| 投入 | 投入总额 | 获利 | 净利润 |
+------+----------+----------+--------+
| 10 | 10 | 19.6 | 9.6 |
| 21 | 31 | 41.16 | 10.16 |
| 43 | 74 | 84.28 | 10.28 |
| 88 | 162 | 172.48 | 10.48 |
| 180 | 342 | 352.8 | 10.8 |
| 367 | 709 | 719.32 | 10.32 |
| 749 | 1458 | 1468.04 | 10.04 |
| 1530 | 2988 | 2998.8 | 10.8 |
| 3123 | 6111 | 6121.08 | 10.08 |
| 6377 | 12488 | 12498.92 | 10.92 |
+------+----------+----------+--------+

以上就是通过Python计算倍投下注金额,关于更多的倍投方法可自行查阅:?倍投的方案全面讲解如何倍投?,关于投机倒把的名词就科普那么多,正式开始这个令人悲伤的故事吧~

第一章:引子

和往常一样,下午等电梯去吃饭,好基友小A又掏出他的小锤子在那里把玩,抱着好奇心的 我用眼角的余光瞄了一下他在看什么,em...竟然不是那种不堪入目的东西?

在我的威逼利诱(Y威)下全盘托出:别人介绍玩的一款赚钱APP(买彩票)。但是,我记得错网络售彩不是从15年就开始命令禁止了吗。行吧,看了下,私庄(私人庄家)。然后大概看了看APP:

页面非常简单,四个部分:

  • 1.顶部最新一期下注倒计时+用户余额
  • 2.每期开奖结果
  • 3.房间里赌客的投注记录
  • 4.下注面板

规则就是下注结果和出的结果一样就中,根据买的种类有不同的倍率,三分钟开一把,下注最小金额?10元宝?(10块),数据来源?加拿大28?彩票的出奖结果。这种算是?公彩?吧,不是?私彩?。区分的最简单依据就是?有这个项目的多个平台?是不是开奖的结果都是一样的,相比起私彩,公彩稍微稍微公平一点。?私彩?的话,?后台是可以调的?!!!好吧,一向对于投机倒把不怎么感冒的我就没有过多的关注了。不过,他貌似从别人那里搞了个下注的投法,慢慢从20奋斗到102,成功引起了我的注意。

这个所谓靠谱的投法就是:

  • 1.历史记录里,单跟双,多就买谁。
  • 2.历史记录里面,大跟小,少就买谁。
  • 3.每一次亏了下一把就把下注金额在上一把基础上翻倍,每一次赚了下一把下注金额就还原到最低值。 4.循环上面三步骤。如果遇到异常流:当前步骤应该买大小或者单双时,出现历史记录里他们数量相同,则停止一局。

后面果然给他撸到200了:

啧啧,竟然真的从20撸到200,不心动是假的...

但是作为一个从不相信天上掉馅饼的开发仔有着自己的矜持,不模拟一下,打死我也不信,于是我盘算着,自己写个脚本按照这个投法去模拟,模拟一段时间后,看看最后是不是真的赚了。先来抓一波APP的包看看吧,这里用到的是手机抓包工具:?Packet Capture

行吧,token和sign,后面另外抓了下注的接口,一大串,加密,所以基本可以放弃了。然后想逆向找下APP的代码,直接apktool反编译后看到qihoo的包名,擦,360加固,这就触及到我的知识盲区了,我还不会脱壳...

幸运的是,这是公彩,有很多网站会直接公布每一期的结果,比如:?www.kandandan.com/yuce/jnd.ht…?,接着打开Chrome抓下包,先看下页面节点:

可以,看下Network也可以找到这些节点,不是JS加载的,nice,所有要做的就是写一个定时器,每隔3分40秒左右(延时问题)访问一下这个站点,提取一波数据。行吧,直接用Python请求库Requests模拟一波请求就行了,定时任务用?apscheduler?库,最后加上投注相关的算法就可以了,直接给代码,就不解释那么多了。

import requests as r
from bs4 import BeautifulSoup
from apscheduler.schedulers.blocking import BlockingScheduler
current_buy = '单双' # 当前买的类型
current_buy_type = '单' # 当前下注类型
current_buy_money = 10 # 当前投注金额
is_buy_flag = False # 此轮是否购买
first_buy = True # 是否第一次下注
balance = 300 # 剩余金额
sched = BlockingScheduler()
def fetch_result():
 global first_buy
 resp = r.get('https://m.99yuce.com/yuce/jnd.html').text
 bs = BeautifulSoup(resp,'lxml')
 tr_s = bs.find("table",attrs={'id': 'tbe'}).find_all('tr')
 # 获取数字列表
 num_list = []
 for tr in tr_s[2:12]:
 num_list.append(int(tr.find('td',attrs={'class': 'tbe_3'}).text))
 print(num_list)
 # 构建数字文字列表
 num_str_list = []
 for num in num_list:
 if num % 2 == 0:
 num_str_list.append('双')
 else:
 num_str_list.append('单')
 if num > 13:
 num_str_list.append('大')
 else:
 num_str_list.append('小')
 if first_buy:
 first_buy = False
 print("当前余额:",balance," 当前投注金额:",current_buy_money,"当前买的类型:",current_buy)
 else:
 calculate(num_list[0])
 predict(num_str_list)
# 预判
def predict(num_str_list):
 global balance
 global current_buy_money
 global current_buy
 global current_buy_type
 global is_buy_flag
 single_count = 0 # 单出现的次数
 big_count = 0 # 大出现的次数
 for num_str in num_str_list:
 if num_str == '单':
 single_count += 1
 if num_str == '大':
 big_count += 1
 print('单:',single_count,' 大:',big_count)
 # 如果当前这把应该买单双
 if current_buy == '单双':
 if single_count > 5:
 current_buy_type = "单"
 balance -= current_buy_money
 is_buy_flag = True
 print("押单")
 elif single_count < 5:
 current_buy_type = "双"
 balance -= current_buy_money
 is_buy_flag = True
 print("押双")
 else:
 # 相等则跳过
 print("单双相等,跳过这一局,不买")
 is_buy_flag = False
 # 如果当前这把应该买大小
 elif current_buy == '大小':
 if big_count < 5:
 current_buy_type = "大"
 balance -= current_buy_money
 is_buy_flag = True
 print("押大")
 elif big_count > 5:
 current_buy_type = "小"
 balance -= current_buy_money
 is_buy_flag = True
 print("押小 ")
 else:
 # 相等则跳过
 print("大小相等,跳过这一局,不买")
 is_buy_flag = False
# 结算,传入最新的数字
def calculate(latest_num):
 global balance
 global current_buy_money
 global current_buy
 global current_buy_type
 global is_buy_flag
 # 如果没有买直接跳过结算
 if is_buy_flag:
 result_list = []
 if latest_num % 2 == 0:
 result_list.append('双')
 else:
 result_list.append('单')
 if latest_num > 13:
 result_list.append('大')
 else:
 result_list.append('小')
 print('开奖结果:',result_list)
 # 中了(加余额,重置下注金额)
 if current_buy_type in result_list:
 balance += current_buy_money * 2
 current_buy_money = 10
 print("中了!")
 # 没中(下注金额加倍)
 else:
 current_buy_money *= 2
 print("没中~")
 # 无论中没中,切换下一把的下注类型
 if current_buy == '单双':
 current_buy = '大小'
 else:
 current_buy = '单双'
 else:
 print("没有下注,跳过当前轮")
 print("当前余额:",current_buy)
if __name__ == '__main__':
 sched.add_job(fetch_result,'interval',minutes=3,seconds=40)
 fetch_result()
 sched.start()

接着把脚本挂着模拟下注就可以,而且小A玩的时候不用自己去统计,看着投就好了。

经过两个小时的艰辛等待,300跑到390了,卧槽,稳得不行,什么都不干,每小时多50块左右,一天跑个10小时,500进口袋,搞十个号,一天不得5000?,5000*30 = 150000,卧槽,一个月什么都不干15W,有本金了买一堆手机,挂着跑100个号,卧槽,深圳买房不是梦。我还盘算着公司附近哪租个小地方来做机房,就一个架子然后放一堆手机就好了。?在不知不觉中我已经着道了?,但还保留着一丝理智,无本生利的事情怎么别人想不到,庄家都是傻逼吗?万一卷款跑路了,于是我谷歌搜了一波是不是骗局,在逼乎看到了这篇文章:?腾讯彩票游戏幸运28是不是个骗局??,现在提是能提现,最怕是做了什么限制,比如次数,或者限额,钱根本搞不出来,抱着先试试,300而已,赚够本金就提出来,后面的就真的是无本生利了(事实是,?我们想多了?,这么点钱,对人家平台来说真的不算什么,而且本金就没提出来过,最后都是血本无归...)

第二章:如火如荼

贫穷使人勤劳,一想到可以暴富,我比任何时候都勤快,真·撸起袖子加油干。所谓的自动化就是不用自己点点点,方法也很简单,使用的Android的?无障碍服务——AccessibilityService实现,原生的Android页面都可以用这个点点点,如果是内嵌网页的就无能为力了。如果你想了解AccessibilityService可以查阅我以前写的两篇文章:

  • 妙用AccessibilityService黑科技实现微信自动加好友拉人进群聊
  • 自动抢红包,点赞朋友圈,AccessibilityService解放你的双手

简单点说就是利用工具,?根据ID或者TEXT文本?,?找到对应的控件?,?进行一些操作?,?比如最常见的点击?,?传入文本等?。而这个找ID的工具可以使用?android-sdk?里自带的?monitor来查找,如果你的手机有root还可以下载使用?开发者助手?,如图所示,可以直接拿到控件ID。

模拟点,进入到这个页面,然后把Python写的算法搬运到Android上,用Okhttp模拟下请求。代码比较多,而且本节主要是将Python,就只贴下大概的样子。

花了一早上的的时间撸出了这个自动点点点,自动下注演示:

行吧,自动下注的点点点弄好了,接着就是挂机测试了,因为觉得稳赚的,于是我注册了两个账号,分别充了300,挂着运行:

在一段小测后发现挺稳定的,于是乎把脚本打成APK,让基友也用起来,然后开始说各种幻想暴富的骚话。

接着就是挂机,BUG修复,和不断的程序优化了,短短几天迭代了十几个版本。接着把基友小B也忽悠进来。

为了早日实现完全自动化,在狗东买了本逆向的书,打算利用国庆破解一波接口,把脚本挂到服务器上,暴富似乎指日可待了,实际上却是一步一步在将自己推向深渊...

第三章:噩耗

2018.9.30号晚上,看着挂了一整天的脚本余额1380元宝,不禁心中窃喜,毕竟有什么比得上看着钱一点点变多令人愉悦么,一想到把脚本挂一晚上,第二天起来就可以2000+了,梦里都会笑醒吧。

2018.10.1号的早上,没有像往常那样睡懒觉到十一二点,八点多就醒了,第一件事迫不及待的去看余额,但是等待我的,却不是如期的2000多,而是340。怎么会这样???不是很稳的吗。立马去翻历史下注记录:

排查后是下注操作有问题,大概的原因可能是: APP开奖延迟,时间并不准确,爬取开奖站点存在一定的延时,有时获到的前十期的结果并不是最新的。 一想到:挂了好几天,钱一下子就没了:

本金用了900,减去剩下的340,我?亏了560?啊,怎么行,必须得回本,昨晚是因为自动挂着才会这样,手动就可以,但是340可以 抗的波数不多,需要更多的本金,我犹豫着要不要充多940进去,凑够1280,在支付的页面停顿了一会儿,后面脑子一热手指一按, 就支付了。不得不说,越来越便捷的支付方式,让人对钱的感觉越来越没感觉,以前没钱了,还要跑银行ATM排队取,钱取出来拿在 手上还会掂量掂量,钱是有分量的。而快捷支付让人感觉钱就是一堆数字而已,越加容易冲动消费,在不知不觉中已经负债累累。 钱充之后,依旧挂着脚本,而基友小A则去问别人拿新策略了。一边继续挂着,一边开始排查程序错误,一开始还是挺稳健的,然而 就一下午的事情,我刚充的钱又败完了,而小A充1000用的新策略也输光了。

小A败光了就放弃了,而我像魔怔了一样,觉得是本金还是不够,而且抗的波数不够,既然害怕这种连续出现的情况, 为何我不直接跟连续呢,比如出现3次连续,我才开始继续买连续,我又充了2560进去,能够抗十三波一直不中。 同样,测试初期都是好的,又挂了一晚上,事实证明,我还是太naive了,早上六点多起来还是赚的,睡了个 回笼觉,八点多起,发现钱又输光了...心情一下跌落到谷底,唉,不知不觉就输了四千多,四千多啊!!! 难过得饭都吃不下,狗东给我打电话让我到楼下拿书都没接,我到底在干嘛啊?并立下各种Flag,再碰投机 倒把的东西,是狗。

第四章:真香

正当我想着算了,花4000多买个教训吧,以后别相信这种投机倒把的东西就好,剩下几天好好写书,别再折腾这些东西。 然而世间万物都离不开『?真香定律?』。

晚上小A又给我案例了一个新的APP

相比起之前的APP,这个是可以?1块起投?的(之前的10块)。

行吧,我又冲了?2426?进去,只是想回本...因为还没有出策略,所以我还是用的之前那个平台的策略买, 下注的基数小了,能抗的波数多了,就稳了,然而结果依旧是输得一干二净。

小A开始疯狂炫富:

在我的再三催促下下,小A终于把下注的策略画出了如下这个下注流程图。

行吧,流程图看上去很复杂,其实捋一捋就是下述这样的策略(只买单双):

  • 1.最新两条记录结果不一样,连续三次一样,连续八次一样,买相反。
  • 2.最新两条记录结果一样,连续四次一样,连续少于七次,买相同。

行吧,策略搞到手了,接着就是抓包和用Python编写爬虫来模拟下注了。

第五章:神兵加持

打开APP,开发者工具打开布局边界,内容面板没有出现边界,行吧不是原生Android,基本就是H5了。 打开?Charlse抓包工具?抓下包(抓包教程可自行百度),可以看到APP陆陆续续发出的请求。

点开其中一个?lotteryOpenCache?可以看到对应的响应的结果如下(?浏览器插件JSON-Handle?):

行吧,大概可以确定是每一把的开奖结果的接口了,接下来是看下传递的参数:

行吧,就是传递JSON数据,但是这个开奖结果要登录后才能访问,肯定是存在cookies或者token这里机制的, 果不其然,点击Cookies选项可以看到:

最后看下请求头如下:

行吧,参数啥的,都有了,我们用Python?requests库?来模拟一波请求吧,看是否能得到对应的结果。

import requests as r
headers = {
 'origin': 'https://m.sfcappwz4.com','user-agent': 'Mozilla/5.0 (Linux; Android 8.1.0; OE106 Build/OPM1.171019.026; wv) AppleWebKit/537.36 (KHTML,like Gecko) Version/4.0 Chrome/62.0.3202.84 Mobile Safari/537.36','content-type': 'application/json','cookie':'JSESSIONID=BDCD384F2DAD64E83BC1A6EBFCADB479','referer':'https://m.sfcappwz4.com/lottery/K3/OG1K3','x-requested-with':'com.bright.aiwprtuon'
}
def get_result():
 resp = r.post('https://m.sfcappwz4.com/tools/_ajax/cache/lotteryOpenCache',headers=headers,json={"requirement": ["OG1K3"]})
 print(resp.json())
if __name__ == '__main__':
 get_result()

运行后输出结果如下:

行吧,可以正确拿到数据,接着我们就该考虑如何获得这个Cookie了,这里后台比较顽皮,它不是在登录成功后 分配Cookies,而是在进去APP的时候就分配了,后续如果登录成功才会一直使用这个Cookie。

后续的所有请求都是带着这个cookie。

行吧,就是先访问这个?getSiteInitData?接口,拿到响应头里的?set-cookie?,保存,然后去执行登录, 接着我们来看下登录接口,也是传递的JSON字符串:

一看参数大概就能猜出什么了,依次是:账号,密码,有效码,时间,是否默认登录,除了密码,其他参数 都比较简单,固定字符串,时间戳,密码的话,猜测是MD5,复制下字符串往网上在线MD5解密网站一丢:www.cmd5.com/,果不其然:

行吧,接着就是模拟登录了,这里用到?hashlib库?进行md5加密:

import hashlib
hl = hashlib.md5()
def auto_login():
 global accountId
 hl.update(account_pawd.encode(encoding='utf-8'))
 json_params = {
 'loginName': account_name,'loginPwd': hl.hexdigest(),'validCode': '','validateDate': str(int(round(time.time() * 1000))),'isdefaultLogin': 'true'
 }
 headers['referer'] = 'https://m.sfcappwz3.com/login'
 headers['x-requested-with'] = 'com.bright.aiwprtuon'
 resp = r.post('https://m.sfcappwz3.com/tools/_ajax/login',json=json_params,headers=headers)
 # 获取accountId
 accountId = resp.json()['data']['user']['userDetail']['accountId']

模拟登录成功后,带着Cookie就可以去访问所有的接口了,其他的接口也是如法炮制,设置请求头,传对应 的数据,这里就不重复复述了,都是些繁琐的操作,加上策略直接给完整脚本。

"""
自动投脚本
"""
import hashlib
import time
import requests as r
from apscheduler.schedulers.blocking import BlockingScheduler
cookies = ''
accountId = '' # 用户id
playIds = ['K3002001010','K3002001011'] # 玩的种类,依次是大小和单双
is_first_open = True # 是否刚打开
result_list = [] # 存储所有结果的数组
purchase_base = 100 # 购买基数
ratio = 1.96 # 中奖倍率
price_list = [] # 投入金额
cur_price_pos = 0 # 当前投入金额游标
cur_purchase_type = '' # 当前下注的类别
account_name = '' # 账号
account_pawd = '' # 密码
cur_money = 0 # 当前余额
hl = hashlib.md5()
headers = {
 'origin': 'https://m.sfcappwz4.com','accept': '*/*','accept-language': 'zh-CN,en-US;q=0.9'
}
# 1.模拟访问拿到Cookies
def fetch_cookies():
 global cookies
 resp = r.post('https://m.sfcappwz4.com/tools/_ajax/getSiteInitData',json={"requirement": ["footerConfig","helpConfig","h5BannerList","gradeList","noticeData","rankingList","activityConfig","defaultPhotoList","lotteryConfig","lotteryList","rewardData","config"],"cacheData": {}})
 cookies = resp.headers['set-cookie'].split(';')[0]
 headers['cookie'] = cookies
# 2.模拟登陆
def auto_login():
 global accountId
 hl.update(account_pawd.encode(encoding='utf-8'))
 json_params = {
 'loginName': account_name,headers=headers)
 # 获取accountId
 accountId = resp.json()['data']['user']['userDetail']['accountId']
# 3.获得开奖结果
def get_result():
 global is_first_open
 global result_list
 headers['origin'] = 'https://m.sfcappwz4.com'
 headers['cookie'] = cookies
 headers['referer'] = 'https://m.sfcappwz4.com/lottery/K3/OG1K3'
 headers['x-requested-with'] = 'com.bright.aiwprtuon'
 resp = r.post('https://m.sfcappwz4.com/tools/_ajax/cache/lotteryOpenCache',json={"requirement": ["OG1K3"]})
 num_list = []
 # 获取最新期数
 curissueNo = int(resp.json()['data']['backData']['lotteryOpen'][0]['issueNo']) + 1
 curissueNo_str = str(curissueNo)
 # 判断是不是最后一期,是的话更新为第二天的第一期
 if curissueNo_str[8:len(curissueNo_str)] == '1441':
 curissueNo = time.strftime('%Y%m%d') + '001'
 print("最新期数:",curissueNo)
 for n in resp.json()['data']['backData']['lotteryOpen']:
 num_list.append(n['count'])
 if len(result_list) == 0:
 result_list.extend(num_list)
 elif len(result_list) == 10:
 result_list.insert(0,num_list[0])
 result_list.pop()
 return curissueNo
# 4.获取当前余额的方法
def get_money():
 global cur_money
 headers['origin'] = 'https://m.sfcappwz4.com'
 headers['cookie'] = cookies
 headers['referer'] = 'https://m.sfcappwz4.com/userCenter/userCenterMenu'
 headers['x-requested-with'] = 'com.bright.aiwprtuon'
 resp = r.post('https://m.sfcappwz4.com/tools/_ajax//getUserBanlance',json={"userName": account_name})
 cur_money = float(resp.json()['data']['money'])
 print("当前余额:",resp.json()['data']['money'])
 init_purchase_list()
# 5.自动下注的方法
def auto_buy(choose,curissueNo):
 global cur_purchase_type
 cur_purchase_type = choose
 playId = playIds[1] # 下注类别id
 buy_price = purchase_base
 # 如果游标到达危险阀值,只投10块
 if cur_price_pos >= len(price_list) - 1:
 if len(price_list) == 1:
 buy_price = 1
 else:
 buy_price = 10
 else:
 buy_price = price_list[cur_price_pos]
 json_params = {
 'accountId': accountId,'clientTime': str(int(round(time.time() * 1000))),'gameId': 'OG1K3','issue': str(curissueNo),'item': [str({
 'methodid': 'K3002001001','nums': 1,'rebate': '0.00','times': buy_price,'money': buy_price,'playId': [playId],'mode': '1','issueNo': str(curissueNo),'codes': choose
 })]
 }
 headers['origin'] = 'https://m.sfcappwz3.com'
 headers['cookie'] = cookies
 headers['referer'] = 'https://m.sfcappwz3.com/lottery/K3/OG1K3'
 headers['x-requested-with'] = 'com.bright.aiwprtuon'
 resp = r.post('https://m.sfcappwz3.com/tools/_ajax/OG1K3/betSingle',json=json_params)
 if resp.json()['code'] != 'success':
 print(resp.text)
 print("下注【",choose,"】 金额【",buy_price,"】")
 print('=' * 50)
# 6.下注算法
def predict():
 global result_list
 global cur_price_pos
 global cur_purchase_type
 curissueNo = get_result()
 print("开奖数字:",result_list)
 size_str_list = []
 single_str_list = []
 for num in result_list:
 if num > 10:
 size_str_list.append('大')
 else:
 size_str_list.append('小')
 if num % 2 == 0:
 single_str_list.append('双')
 else:
 single_str_list.append('单')
 print("大小结果:",size_str_list)
 print("单双结果:",single_str_list)
 # 获取第一项
 size_first = size_str_list[0]
 single_first = single_str_list[0]
 # 判断上一把有没有中,中了重置投钱下标
 if cur_purchase_type == '':
 pass
 elif cur_purchase_type == size_first or cur_purchase_type == single_first:
 cur_price_pos = 0
 print("中了!!!")
 get_money()
 else:
 cur_price_pos += 1
 print("没中!!!")
 # 判断相同记录条数
 repeat_count = 1
 for single in single_str_list[1:8]:
 if single == single_first:
 repeat_count += 1
 else:
 break
 if repeat_count in [1,3,8]:
 if single_first == '单':
 auto_buy("双",curissueNo)
 else:
 auto_buy("单",curissueNo)
 elif repeat_count == 2:
 if single_str_list[2] == single_str_list[3]:
 if single_first == '单':
 auto_buy("双",curissueNo)
 else:
 auto_buy(single_first,curissueNo)
 elif repeat_count in [4,5,6,7]:
 auto_buy(single_first,curissueNo)
# 构建倍率列表,保证赢前后收益 - 投入 > 购买基数
def init_purchase_list():
 global price_list
 cost = purchase_base
 price_list = [purchase_base]
 # 其他进行动态计算
 for i in range(10):
 # 购买价格其实区间(2倍)
 start_price = purchase_base * (2 ** i)
 # 购买价格极限区间(3倍)
 end_price = purchase_base * (3 ** i)
 # 保证没把不亏就行
 for j in range(start_price,end_price + 1):
 if j * ratio - cost - j > 1 and cost + j <= round(cur_money / 2):
 cost += j
 price_list.append(j)
 break
 print("生成投入金额列表:",price_list)
# 重新登录
def login_again():
 print("重新登录!")
 fetch_cookies()
 auto_login()
if __name__ == '__main__':
 init_purchase_list()
 fetch_cookies()
 auto_login()
 predict()
 scheduler = BlockingScheduler()
 # 每隔60s下注一次
 scheduler.add_job(predict,max_instances=10,seconds=60)
 scheduler.start()

接着就可以把脚本丢到云服务上执行了,这里用的是nohup命令让脚本在后台运行。

nohup python3 -u xiaozheng.py > xiao.out 2>&1 &

然后执行?tail -f xiao.out?或者?cat xiao.out?可以查看到日志输出记录。

因为用的是官方的接口,也没有出现接口延迟的问题...一切貌似就这样顺理成章的执行着, 然而最后的结果,依旧躲不过输得一干二净。

我开始反省,为何剧本的最后结局都是输光,人投也是采用相同的策略,人赚,脚本投就亏。

  • 1.脚本24小时跑,?策略固定?,而彩票规律可能是不断变化的,人偶尔也会变通下;
  • 2.人不会一直买,而且出现连续不中的时候会停止观察,找稍微稳定一点的时间点切入;

既然这样固定策略必凉,为何不让别人在投的时候,顺道也帮我投了呢,?爱屋及乌?!

第六章:爱屋及乌

在我输光输净后小A又疯狂的炫富:

既然小A那么稳,为何不让他投的时候帮我也投了呢,坐收渔翁之利。行吧,既然接口我都有了,为何不能 自己写个APP呢?所以有了下面这样的计划:

  • 1.先写一个APP,小A登录的时,顺带也登录下我的账号,然后下注的时候,我的账号也跟着下注。
  • 2.编写API接口给APP调用,小A下注的时候顺带调用这个接口,后台接收到下注信息,批量下注。

正当我准备打开自己写好的APP截个图的时候,发现自己写的APP竟然登录不了了,啧啧,应该是昨晚 维护了,把接口改了。

行吧,顽皮,批量替换下基地址,登录成功后,竟然又自动退出来了。利用?Android Profiler性能调优工具 抓一波包,login接口是success的,lotteryOpenCache的响应码竟然是?nologin?:

猜测是Cookie变了,打开它们的APP登录,打开结果页,抓包看看:

果不其然,多了个sto-id-20480,左侧搜下这个串东西,在哪里拿到的,过滤下,只查看响应头:

定位下可以找到:

接着是另外一段:JSESSIONID=53287B9851CF658D255A029F1426C82A,如果炮制找出是在哪个接口 的响应头set-cookie的,如下:

总结下就是依次:

  • 1.访问:m.suibianwanba.com/ 拿sto-id
  • 2.访问:?m.suibianwanba.com/tools/_ajax…?拿JSESSIONID

后续所有访问请求头cookie设置为这两个字符串即可,同样贴出大概的代码,显示接口:

然后是调用页面:

APP的下注页面:

页面简陋,但是功能齐全,好吧,接着就把APP丢给小A先帮我投着先,接下来就是写接口给自己的APP调用了, 不然怎么弄成批量的方式,这里用到的Python轻量级Web库:?Flask?。

直接通过pip命令进行安装即可:?pip install flask?,官方的一个最简单示例:

# coding=utf-8
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
 return "Hello Flask!"
if __name__ == "__main__":
 app.run()

运行后打开127.0.0.1:500可以看到返回了Hello Flask!

关于Flask的使用,这里不会讲解,因为也不涉及到什么高深内容,更多内容可以自行查阅官方文档:?flask.pocoo.org/docs/1.0/?简单说下我们要做的事情,需要两个接口(传参用Json字符串)。

  • add_account?:?添加账号?,?POST?,传参:用户名与密码,拿到数据后模拟登录,拿到对应的Cookies,存到MySQL数据库中;
  • bet?:?下注?,?POST?,传参:下注类型与下注金额,拿到数据后批量调用下注方法。

行吧,官方貌似又改接口了,又重新抓了一波包(其实就是改了跟地址而已)...

限于篇幅,不太过具体的去讲解代码,显示工程的结构:

创建了一个app目录,下面有一个 __init__.py 文件:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config.from_object('config')
db = SQLAlchemy(app)
from app import models,views

代码中初始化了一个Flask实例,读取配置文件,创建了一个SQLAlchemy实例,导入了models和views文件。 config.py内容如下:

SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:Jay12345@localhost:3306/q9g'
SQLALCHEMY_TRACK_MODIFICATIONS = True

然后是定义数据结构:?账户名+密码+Cookie+账户ID(下注用)?,这里并不使用原生SQL语句去操作MySQL数据库,而是使用ORM框架——?SQLAlchemy?,直接通过pip命令安装即可:?pip install flask-sqlalchemy?,model.py的代码如下:

from app import db
class User(db.Model):
 __tablename = 'user'
 __table_args__ = {'useexisting': True}
 _id = db.Column(db.Integer,primary_key=True,autoincrement=True)
 account = db.Column(db.TEXT)
 pwd = db.Column(db.TEXT)
 cookies = db.Column(db.TEXT)
 accoutId = db.Column(db.TEXT)
 @property
 def id(self):
 return self.id
if __name__ == '__main__':
 db.create_all()

还有安装一个?flask-script?模块,用于通过命令行来操作Flask,同样可以通过pip命令进行安装:?pip install flask-script?,新建一个manager.py,在里面启用Flask项目。

from app import app
from flask_script import Manager
manager = Manager(app)
if __name__ == '__main__':
 manager.run()

准备工作差不多了,接着开始编写我们的登录接口:

import hashlib
import time
import requests as r
from flask import request,jsonify
from app import app,db
from app.models import User
headers = {
 'origin': 'https://m.suibianwanba3.com','user-agent': 'Mozilla/5.0 (Linux; Android 8.1.0; OE106 Build/OPM1.171019.026; wv) AppleWebKit/537.36 '
 '(KHTML,like Gecko) Version/4.0 Chrome/62.0.3202.84 Mobile Safari/537.36 ','x-requested-with': 'com.bright.extnetiop',}
@app.route("/add_account",methods=['GET','POST'])
def add_account():
 account = ''
 pwd = ''
 if request.method == 'GET':
 account = request.args.get("account")
 pwd = request.args.get("pwd")
 elif request.method == 'POST':
 account = request.json['account']
 pwd = request.json['pwd']
 # 密码加密
 hl = hashlib.md5()
 hl.update(pwd.encode(encoding='utf-8'))
 # 实例化用户实例
 user = User()
 user.account = account
 user.pwd = hl.hexdigest()
 msg = auto_login(user)
 return jsonify(
 {'code': '200','data': [{'account': account,'pwd': pwd}],'msg': (msg if msg is not None else "登录成功")})
@app.route("/bet",'POST'])
def bet():
 choose = ''
 price = ''
 cur_no = ''
 if request.method == 'GET':
 choose = request.args.get("choose")
 price = request.args.get("price")
 cur_no = request.args.get("cur_no")
 elif request.method == 'POST':
 choose = request.json['choose']
 price = request.json['price']
 cur_no = request.json['cur_no']
 # 批量下注
 result_list = []
 users = User.query.all()
 for user in users:
 result_list.append(auto_bet(user,price,cur_no))
 return jsonify({'code': '200','data': result_list,'msg': '访问成功'})
# 获取Cookie
def fetch_cookies(user):
 if 'cookie' in headers:
 headers.pop("cookie")
 cookie_resp = r.post("https://m.suibianwanba3.com/tools/_ajax/cache/getSiteInitData","cacheData": {}})
 if cookie_resp is not None:
 cookie = cookie_resp.headers.get('set-cookie')
 if cookie is not None:
 headers['cookie'] = cookie.split(';')[0]
 user.cookies = cookie.split(';')[0]
# 模拟登录
def auto_login(user):
 fetch_cookies(user)
 json_params = {
 'loginName': user.account,'loginPwd': user.pwd,'isdefaultLogin': 'true'
 }
 resp = r.post("https://m.suibianwanba3.com/tools/_ajax/login",json=json_params)
 if resp is not None:
 if resp.json()['code'] == 'success':
 user.accoutId = resp.json()['data']['user']['userDetail']['accountId']
 db.session.add(user)
 db.session.commit()
 else:
 print(resp.json()['msg'])
 return resp.json()['msg']

运行项目,然后使用浏览器或者PostMan模拟请求:

调用这个接口数次,获取账户名+密码+Cookie+账户ID,然后存入数据库,存入后的结果如图所示:

可以,都存到数据库里,接着我们来编写下注接口:

playIds = ['K3002001010','K3002001011'] # 下注种类,依次为大小和单双
@app.route("/bet",'msg': '访问成功'})

下注

def auto_bet(user,cur_no):
play_id = playIds[0]
if choose in ['单','双']:
play_id = playIds[1]
json_params = {
'accountId': user.accoutId,'issue': str(cur_no),'times': price,'money': price,'playId': [play_id],'issueNo': str(cur_no),'codes': choose
})]
}
headers['cookie'] = user.cookies
resp = r.post('https://m.suibianwanba3.com/tools/_ajax/OG1K3/betSingle',json=json_params)
print(resp.json())
return resp.json()

同样模拟请求一波,看看响应的结果:

这里没有做cookie过期的相关处理逻辑,做的话也比较简单,对异常信息进行过滤,然后调用登录相关的 方法重新登录,更新一下数据库里账户对应的Cookie即可。

行吧,本地接口跑通了,接下来把项目部署到服务器上,让外网能够访问我们的接口,感觉用Docker部署 就有点装逼了,所以这里还是只用FTP/SFTP工具把代码上传到云服务器上。

第七章:言听计从

官方维护...明天再更

第八章:屠龙计划

官方维护...明天再更

第九章:终章(填坑)

1.到底什么是洗钱 2.彩票开奖结果真的是随机的吗? 等等...

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读