支付宝自动化薅羊毛


说实话我真的佩服自己,明明期末复习了,还要“头铁”的搞这些东西,表示对期末的成绩将会很担心。没办法谁让马云将支付宝红包活动又延长了呢。2018年刚到就增加支付宝红包的金额。在过去的2017年用分享给支付宝好友链接的方式“薅”得了300元。随着红包的额度增大怎么能安心呢!

这样每天早上6:30便起床开开心心的分享红包链接。200多个好友分享完一次就要200/9次的重复的动作,但是时间长了多些无味的感觉,重复性的动作在Python的程序理念中是不可取的,“永远都不要重复你自己”。

添加广告:如果看完这篇文章你还不想打赏,就破例扫一下我的红包码,也相当于给我打赏了,别管一毛两毛都是钱!或者加支付宝好友感受一下每天被闹钟似的支付宝红包


内容介绍

如何让我的手脱离手机去发送分享支付宝的链接?程序,Python程序。在最初的时候想着支付宝有没有像微信一样的程序接口,去批量的给支付宝中的好友去发送红包的链接,查找资料后,发现支付宝只提供商业的接口,再下面一点的接口不提供了。也许是担心安全和骚扰问题!

在年末火的微信跳一跳中,程序辅助中用到了ADB,ADB是Android操作系统与桌面电脑间沟通的一个命令列工具。可以在电脑上通过命令达到操作手机的效果。这个工具可以说在测试中的等级范围属于低级的一种。能达到的效果:我在手机上的各种操作(点,滑动,写文字,截屏)都可以通过ADB使用命令的方式实现。具体的使用方法在上一篇文章中有详细的讲述。在上篇的文章中adb应用的方面在“截屏”、“传输数据”与“按压”。本篇文章中将生活中的事件抽象模型化,完成简单的数理建模,使用ADB的“滑动”与“按压”的组和完成“自动化”分享支付宝红包链接。

分为这几个步骤,介绍上篇文章的流量。
搞这个东西的原因,受什么启发
贴上一波女朋友的广告

贴上支付宝码,要钱 打赏一次
电脑端
手机端保存图片


准备工具:


施行方案

  • 位置测距

  • 抽象模型

  • Python代码


###位置测距
操作手机使用adb,原理与使用方法参考详细介绍。在平常使用手机过程中,最常用的动作就是点点点,滑滑滑。模拟分享红包链接的过程中也使用到了两步

一个是上下左右滑动

adb shell input swipe x1 x2 y1 y2

另一个是点击

adb shell input tap x y

X、Y是手机的分辨率像素对应的位置。手机上左上位置坐标为(0,0),相应的右下的坐标(Xmax,Ymax)。每一个位置都可以通过坐标的方式表达,例如滑动屏幕是从一个坐标到另一个坐标,点击屏幕是直接tap坐标,获取分辨率的方法

adb shell wm size

例如:我的手机720*1280,宽720,长1280

点击某个位置

abd shell input tap 100 100

这时候点击位置,但是这个(100,100)如何快速的确定呢!

发明出专用的“尺子”


根据手机的尺度打造一个度量,方便后期进行测量大概的位置。

ADB中input的常用方法,具体内容参见我上篇文章

1
2
3
4
5
6
7
8
D:\>adb shell input
usage: input ...
input text <string>
input keyevent <key code number or name>
input [touchscreen|touchpad|touchnavigation] tap <x> <y>
input [touchscreen|touchpad|touchnavigation] swipe <x1> <y1> <x2> <y2> [duration(ms)]
input trackball press
input trackball roll <dx> <dy>

抽象模型

其实发送的过程就两个大的过程。

  • 点击发送按钮

  • 多选联系人

点击发送按钮

实现点击发送按钮的过程十分的简单。例如下图中需要点击“发送”,就只需要定位到发送按钮的位置区域,在这个区域内点击任何一个点即可完成发送的动作。

实现代码
定位到发送按钮的位置的一点(600 650)

1
2
import os
os.system('adb shell input tap 600 650') # 完成发送

点击按钮是属于傻瓜式的操作,在与去准确的测量其位置信息,找到对应的位置的信息即可完成操作,同样比如发送、确定、取消等出现在手机上的可点可选内容都能操作。

多选联系人

为了做到快速的发送链接给好友,使用多选联系人发送方式,选择每次点击联系人便能加入到多选框,支付宝的限制每次的多选在0~9人的范围,最多不能超过9人。

依照字母格式将整个联系人分成26组。例如定位到A组后,A组中有9位联系人,确定第一位联系人的点击位置,然后第二位联系人在第一位联系人的基础上加上一个联系人的长度(测试长度为111)。

实现9个联系人。

1
2
3
4
5
6
first =  初始位置
for i in range(9): # 循环点击联系人
point = first + i * 111
print('固定9个人的位置:',point)
os.system('adb shell input tap 220 ' + str(point) + ' ') # 点击联系人的位置
time.sleep(0)

现在整个实现过程的主干已经清楚了,再优化逻辑。

首先如果以某一个字母开头的联系人未满足9人或者超过9人,我们的不再代码适用,选择可以更改的易维护的方案。将某个以字母开头的所有联系人记录,然后判断是否超过9人,如果超过9人,就选着9个人,然后总人数减去9;如果人数达不到9人,便将人数加入到上面代码中的range()位置。

在算法中超过9次每次经历一个全选的过程都减去一次9,例如A中的人数有19个,每9次一个循环,需要进行3次循环分别是第1次选择9人,第2次选择9人,第3次选择1人。这样来来回回的减去i*9个数字略显智障。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
for w in range(int(math.ceil(总人数/9))+1):    # 总人数分成9人/组,能分成组数
if w==0:
pass
else:
if w==int(math.ceil(总人数/9)): # 如果人数不够9人/组,就只选剩下的人
for i in range(剩下的人数): # 循环点击联系人
point = first + i * 111
os.system('adb shell input tap 220 ' + str(num2) + ' ')
time.sleep(0)
else: # 人数超过9人/组,进行一组满的选择
for i in range(9): # 循环点击联系人
point = first + i * 111
os.system('adb shell input tap 220 ' + str(num2) + ' ') 点击固定9的联系人的位置
time.sleep(0)

在实际的应用中发现,选择7~9个人后最后发送的过程中,有两行联系人头像的位置,而6个人以下(包括6人)只有一个人的头像位置,这样发送的位置就不能固定,于是将分组改成6人,进而避免了来回判断位置的情况。

1
2
3
4
5
for w in range(int(math.ceil(总人数/6))+1):      # 总人数分成6人/组,能分成组数
if w==0
pass
else:
程序

这样我们就有基础了,可以走一遍发送的整个过程,每次发送完成后会返回到支付宝红包的首页,每次都是从首页开始进行

选择依字母开头的联系人,定位到字母联系人的位置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
list=['*','a','b','c','d'······]                 # 建立列表便于遍历
dic2={
'0':0, # *
'1':29, # a
'2':14, # b
'3':19, # c
'4':8, # d
······
} # 创建字典 里面的值是对应通讯录中的人数
for l in range(列表长度):
zero = int(304) # 通讯录右边 最初的位置
num = zero + 36 * l # 每一个字母之间的位置大概 36
time.sleep(1)
os.system('adb shell input tap 700 ' + str(num) + '') # 选择通讯录最右边字母

然后去选择联系人。超过6个人就去选满6人,然后等下次在定位到这个字母联系人的时候,就要把6个人去舍弃掉,可以转化为不再选这6个人,也就是向下滑动6个联系人的单位。

1
2
3
4
for i in range(int(w)-1):                        #减去1,当w=1时候就不用滑动了。
time.sleep(1)
print('要向下滑动{}个单位,此时滑动到{}个单位'.format(i,int(w)-1))
os.system('adb shell input swipe 400 900 400 300 1000') # 滑动的位置都是经过多次的实验得到的

在发送红包的时候可以写一段留言

1
adb shell input text Red_bagre            写下一段文字


Python代码

完整代码,鄙人手拙。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import os
import time
import sys
import math
list=['*','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','#']
dic2={
'0':0, # *
'1':29, # a
'2':14, # b
'3':19, # c
'4':8, # d
'5':0, # e
'6':6, # f
'7':12, # g
'8':12, # h
'9':0, # i
'10':11, # j
'11':1, # k
'12':61, # l
'13':7, # m
'14':4, # n
'15':2, # o
'16':6, # p
'17':4, # q
'18':3, # r
'19':17, # s
'20':8, # t
'21':0, # u
'22':0, # v
'23':28, # w
'24':15, # x
'25':16, # y
'26':28, # z
'27':0 # #
} #
a = 0
for i in range(28):
a = a + dic2[str(i)]
print(a) #总共有联系人
def alipay():
flag = os.system('adb devices')
if flag == 1:
print('安装adb或配置环境便令')
sys.exit()
os.system('adb shell input keyevent 3') #依照我手机的图形摆放位置
os.system('adb shell input keyevent 3') # 返回到home键
os.system('adb shell input swipe 600 600 300 600')
os.system('adb shell input swipe 600 600 300 600') # 向左滑动两次
os.system('adb shell input tap 280 100') # 点击打开支付宝的位置

os.system('adb shell input tap 80 1250') # 定位到首页的位置
time.sleep(5)
os.system('adb shell input swipe 400 1150 400 300')
os.system('adb shell input tap 600 400') # 发红包赚赏金

for l in range(28): # 大的循环 没发一次就循环一次的,每一个字母循环一次
for w in range(int(math.ceil(dic2[str(l)]/6))+1):
if w==0:
pass
else:
print('以{}开头联系人,第{}位,要循环的{}次,此时第{}次循环'.format(list[l],l,int(math.ceil(dic2[str(l)]/6)),w))
time.sleep(4)
os.system('adb shell input tap 388 1088') # 立即赚赏金
time.sleep(1)
os.system('adb shell input tap 688 938') # 发送给朋友
time.sleep(1)
os.system('adb shell input tap 666 100') # 点击多选
time.sleep(1)
os.system('adb shell input tap 300 300') # 从通讯录选择
# # 循环选着联系人
a = int(304)
num = a + 36 * l
time.sleep(1)
os.system('adb shell input tap 700 ' + str(num) + '') # 选择字母
#
for i in range(int(w)-1):
time.sleep(1)
print('要向下滑动{}个单位,此时滑动到{}个单位'.format(i,int(w)-1))
os.system('adb shell input swipe 400 900 400 300 1000') # 滑动
num3 = 320

if w==int(math.ceil(dic2[str(l)]/6)):

for i in range(dic2[str(l)]-(w-1)*6): # 循环点击联系人
num2 = num3 + i * 111
print('{}要循环{}次,此时第{}次循环,选择到第{}个联系人,距离是{}'.format(list[l],int(math.ceil(dic2[str(l)]/6)),w,i,num2))
os.system('adb shell input tap 220 ' + str(num2) + ' ')
time.sleep(0)
else:
for i in range(6): # 循环点击联系人
num2 = num3 + i * 111
print('{}要循环{}次,此时第{}次循环,选择固定6个人。选择到第{}个联系人,距离是{}'.format(list[l],int(math.ceil(dic2[str(l)]/6)),w,i,num2))
os.system('adb shell input tap 220 ' + str(num2) + ' ')
time.sleep(0)

time.sleep(1)
os.system('adb shell input tap 620 100') # 两次确定
time.sleep(1)
#程序自动发送早上好早上好Good_morning_Program_automatic_transmission
#Good_morning_Happy_day
os.system('adb shell input tap 620 100') # 发送
time.sleep(1.5)
os.system('adb shell input tap 300 840') # 发送
time.sleep(0.1)
os.system('adb shell input text Red_bagre')
time.sleep(0.5)
# os.system('adb shell input tap 522 910') # 发送
os.system('adb shell input tap 600 650') # 发送
time.sleep(2)
#防止网卡。
print('发送成功')

alipay()

里面添加了多处的time,主要还是自己的手机反应慢的原因。不得已而为之。


添加联系人

在经过多次实验,代码可以无误的在我的手机上跑起来,这样分分钟把所有的人跑完了,这样0就觉得联系人太少了额!没几次就发送完了。另外支付宝可以很方便的通过手机通讯录添加联系人。

批量添加联系人

安卓的手机通讯录可以导出.vcf格式。然后传送到电脑上,查看文档的内容


其中的TEL CELL是电话号码,然后批量添加手机号,生成txt中的内容。导入到手机里面更新通讯录,大功告成。

手机号码为了提高可使用率,可以从大学的贴吧中爬取,面向学生获取的手机号,日常的支付宝使用率比较高。

或者去批量的生产几千个

1
2
3
4
5
6
7
8
9
10
with open('00003.txt','w')as f:
for i in range(99):
a = random.randint(1700, 8000)
print(a)
f.writelines('BEGIN:VCARD'+'\n')
f.writelines('VERSION:2.1'+'\n')
f.writelines('N:;'+str(a)+';;;'+'\n')
f.writelines('FN:1'+'\n')
f.writelines('TEL;CELL:132 5337 '+str(a)+'\n')
f.writelines('END:VCARD'+'\n')

实在搞笑的事情,在导入完成后,足足有4000多个电话号码。刚登陆上支付宝的小号准备加人,支付宝立即把我的帐号封了,说我存在风险,然后打客服电话,直接给我封了一个月。可见支付宝的安全措施真的强,那里都不能钻空子,钻到一点空子实属捡到的便宜。

既然你支付宝不让我通过通讯录添加好友,那我就手动的添加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
for i in range(100):
print('第几次添加好友',i)
l = random.randint(1000,9999)
print('手机号是:1599567',l)

os.system('adb shell input text 1325337'+str(l)) # 搜索联系人
time.sleep(3)
os.system('adb shell input tap 680 220') #选择联系人
time.sleep(3)
os.system('adb shell input tap 680 400')
os.system('adb shell input tap 680 500') # 添加好友
os.system('adb shell input tap 680 555')
os.system('adb shell input tap 680 600')
time.sleep(3)
os.system('adb shell input tap 680 100') # 发送
time.sleep(3)
os.system('adb shell input keyevent 4') # back
time.sleep(3)
os.system('adb shell input tap 680 80') #点叉
time.sleep(3)

这几串代码能保证无论是否添加过好友,还是没有搜索到好友,还是允许添加都能应对。

每天最多添加的只有30个好友,多了之后就不让添加了。


总结

在这次的文章中没有什么难的技术上面的问题,主要是应用方面,如何将一系列的问题模型化,程序化。

如何做到自动呢!将电脑的主板改成每天早上6点自动开启,然后定时执行脚本。(让360手机助手不自启动,防止端口占用),现在我的笔记本游戏本,也不支持自启,寝室断电更不能抗住一夜,回去用家里的台式机进行实验。(我记得我的电脑能通过调节主板把频率和功耗降到最低。不过也不值得我去倒持它了。)

理论化分析:活动举行3个月,支付宝好友最多有500人的上限,每天能添加30人,就算一天只有10个人去同意,现在我的通讯录有280多人,在未来一个月内能加满人,同时还有一部分人受不了我的骚扰单方面删除我,同时也能保证500人的状态。每天发送500分分享,大概需要一个小时的时间,按照10%的人去愿意点开链接,每天就有500*10%=50个红包,在红包使用后折算不立即使用的人,支付宝领取红包金额最多在0.11元与0.34元最多。但是使用红包后我能获得的奖励金却是翻了几倍的金额。每天收入十几元以上。按照这样想想,月入百万都是梦。

毕竟这些都是理论化的分析,可能根本就到不到这个数值。但是这个方法大家可以去试一下。还有 看到这就去上面扫扫码,各位老爷打赏一下。或者点击加我支付宝好友。备注简书!

祝大家发财!