├── .gitignore ├── README.md ├── config.json └── 蒙牛世界杯抢牛奶.py /.gitignore: -------------------------------------------------------------------------------- 1 | /mengniu-get-milk.iml 2 | /venv/ 3 | /.idea/ 4 | /dist 5 | /build 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mengniu-get-milk 2 | 蒙牛世界杯每天抢牛奶脚本(原创脚本,仅供学习交流使用,每日更新,关注忒星不迷路) 3 | 4 | 2022-12-09 更新至1.3版本 5 | 6 | 2022-12-10 更新至1.4版本 7 | 8 | 2022-12-11 更新至1.5版本 9 | 10 | 2022-12-12 更新至1.6版本 11 | 12 | 2022-12-15 更新至1.7版本 13 | 14 | 2022-12-16 更新至1.8版本 15 | 16 | 2022-12-19 更新至2.0版本 17 | 18 | 使用方法: 19 | 20 | 1.安装python 21 | 22 | 2.安装python模块 cmd执行命令 23 | 24 | pip install pycryptodome 25 | 26 | pip install requests 27 | 28 | 3.修改config.json里面的token即可使用 多开 复制多份exe+配置文件 放在不同文件夹即可 29 | 30 | 4.双击打开py或者用exe即可运行 31 | 32 | 说明: 33 | 活动微信小程序:蒙牛世界杯 34 | 35 | 36 | 交流群:(已满200人 群主wx:g4994g 加我拉你进群) 37 | ![image](https://user-images.githubusercontent.com/49848349/206616062-426f6747-58da-43da-82a3-e676fbf6f436.png) 38 | 39 | 运行截图: 40 | ![image](https://user-images.githubusercontent.com/49848349/206611043-edf5854f-488c-43ff-821a-a74d1d266774.png) 41 | 42 | -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "token": "", 3 | "clientKey": "odzedoYiN5DLKaslkjlk21j23GYFYGFJfRaQRzMUKV4qVaKRm", 4 | "clientSecret": "IjQP8ED8kGavOIK32klj23kl4j23IkpuKXa7afrj96w64dgUiP8ujtL7byHtlGFU3Fv", 5 | "updateUrl": "/mp/api/user/seckill/sada/23123/sdsfij234/fef2/32432", 6 | "threadNumber": 200, 7 | "preTime": 2000, 8 | "desKey": "pZN8^thwwfKl8^oz", 9 | "domain": "https://mengniu-apig.xiaoyisz.com", 10 | "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.30(0x18001e31) NetType/WIFI Language/zh_CN", 11 | "Referer": "https://servicewechat.com/wx8e45b2134cbeddff/67/page-frame.html" 12 | } -------------------------------------------------------------------------------- /蒙牛世界杯抢牛奶.py: -------------------------------------------------------------------------------- 1 | import base64 2 | import datetime 3 | import hashlib 4 | import json 5 | import os 6 | import random 7 | import sys 8 | import threading 9 | import time 10 | 11 | import requests 12 | from Crypto.Cipher import DES 13 | from Crypto.Util.Padding import pad, unpad 14 | 15 | 16 | def printf(text): 17 | ti = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f') 18 | print(f'[{ti}]: {text}') 19 | sys.stdout.flush() 20 | 21 | def desEn(content, key): 22 | key = key[:8].encode('utf-8') 23 | content = content.encode('utf-8') 24 | cipher = DES.new(key=key, mode=DES.MODE_ECB) 25 | content = pad(content, block_size=DES.block_size, style='pkcs7') 26 | res = cipher.encrypt(content) 27 | return base64.b64encode(res) 28 | 29 | def desDe(content, key): 30 | key = key[:8].encode('utf-8') 31 | content = base64.b64decode(content) 32 | cipher = DES.new(key=key, mode=DES.MODE_ECB) 33 | res = cipher.decrypt(content) 34 | res = unpad(res, DES.block_size, style='pkcs7') 35 | return res.decode('utf-8') 36 | 37 | def generate_random_str(randomlength=16): 38 | random_str = '' 39 | base_str = 'ABCDEFGHIGKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz0123456789' 40 | length = len(base_str) - 1 41 | for i in range(randomlength): 42 | random_str += base_str[random.randint(0, length)] 43 | return random_str 44 | 45 | def getTimestamp(): 46 | return int(round(time.time() * 1000)) 47 | 48 | def rcape(v): 49 | if len(v) != 2: 50 | return '0'+v 51 | return v 52 | 53 | def getJsonId(): 54 | global start_time 55 | url = 'https://gz-cdn.xiaoyisz.com/mengniu_bainai/game_configs/prod_v1/game_configs.json?v=1670228082180' 56 | res = requests.get(url=url, headers=head).json() 57 | month = datetime.datetime.now().strftime('%m') 58 | day = datetime.datetime.now().strftime('%d') 59 | day = rcape(str(int(day) - 1)) 60 | 61 | for item in res['activity_data']: 62 | result_id = item['result_id'] 63 | result_id = result_id.replace('result_', '') 64 | json_id = item['json_id'] 65 | if result_id == (month+day): 66 | reward_Num = item['reward_Num'] 67 | start_time = item['start_time'] 68 | printf(f'今日可抢牛奶数量:{reward_Num}') 69 | return json_id 70 | return '' 71 | 72 | def getRKSign(timestamp, nonce): 73 | md5Str = f'clientKey={clientKey}&clientSecret={clientSecret}&nonce={nonce}×tamp={timestamp}' 74 | return hashlib.md5(md5Str.encode('utf-8')).hexdigest().upper() 75 | 76 | def getRk(): 77 | timestamp = getTimestamp() 78 | nonce = generate_random_str(16) 79 | sign = getRKSign(timestamp, nonce) 80 | url = f'{domain}/mengniu-world-cup/mp/api/user/baseInfo?timestamp={timestamp}&nonce={nonce}&signature={sign}' 81 | res = requests.get(url=url, headers=head).json() 82 | printf(res) 83 | try: 84 | return res['data']['rk'] 85 | except Exception: 86 | raise Exception('获取账号rk失败,该token已经触发风控机制,请重新抓包获取新token') 87 | 88 | def getMilkSign(requestId, timestamp, rk): 89 | md5Str = f'requestId={requestId}×tamp={timestamp}&key={rk}' 90 | return hashlib.md5(md5Str.encode('utf-8')).hexdigest() 91 | 92 | def skillMilk(rk, jsonId): 93 | timestamp = getTimestamp() 94 | requestId = generate_random_str(32) 95 | nonce = generate_random_str(16) 96 | signature = getRKSign(timestamp, nonce) 97 | sign = getMilkSign(requestId, timestamp, rk) 98 | url = f'{domain}/mengniu-world-cup-1122{updateUrl}?timestamp={timestamp}&nonce={nonce}&signature={signature}&jsonId={jsonId}' 99 | head['sign'] = sign 100 | head['timestamp'] = str(timestamp) 101 | head['requestId'] = requestId 102 | try: 103 | res = requests.get(url=url, headers=head, timeout=10).text 104 | printf(res) 105 | except Exception as e: 106 | printf(f'超过10s请求超时...') 107 | 108 | def isStart(): 109 | current_time = getTimestamp() 110 | if current_time >= (start_time - preTime): 111 | return True 112 | else: 113 | return False 114 | 115 | if __name__ == '__main__': 116 | try: 117 | with open('./config.json', 'r') as c: 118 | rdConfigStr = c.read() 119 | config = json.loads(rdConfigStr) 120 | except Exception as e: 121 | printf(f'加载配置文件异常:{str(e)}') 122 | os.system('pause') 123 | 124 | ''' 125 | time无需管 服务器获取 126 | ''' 127 | start_time = 0 128 | domain = config['domain'] 129 | 130 | ''' 131 | token是小程序包的请求头的Authorization: 132 | ''' 133 | token = config['token'] 134 | desKey = config['desKey'] 135 | clientKey = config['clientKey'] 136 | clientSecret = config['clientSecret'] 137 | updateUrl = config['updateUrl'] 138 | ''' 139 | 请求头 140 | ''' 141 | head = { 142 | 'User-Agent': config['User-Agent'], 143 | 'Referer': config['Referer'], 144 | 'content-type': 'application/json', 145 | 'Authorization': token 146 | } 147 | 148 | ''' 149 | 账号的rk 自动获取 150 | ''' 151 | rk = getRk() 152 | ''' 153 | 抢多少次最大24 多了触发风控机制 导致无法获取rk 所有接口返回{"code":500,"message":"非领奶时间"} 触发风控机制后需要更新toekn才能恢复正常 154 | ''' 155 | threadNumber = config['threadNumber'] 156 | ''' 157 | 提交几秒开枪(单位毫秒) 158 | 如 2000 就是 8:59:58秒开枪 159 | ''' 160 | preTime = config['preTime'] 161 | 162 | rk = desDe(rk, desKey) 163 | jsonId = getJsonId() 164 | time.sleep(1) 165 | skillMilk(rk, jsonId) 166 | time.sleep(1) 167 | tdList = [] 168 | 169 | for i in range(threadNumber): 170 | tdList.append(threading.Thread(target=skillMilk, args=(rk, jsonId))) 171 | 172 | while True: 173 | if isStart(): 174 | for tdItem in tdList: 175 | try: 176 | tdItem.start() 177 | time.sleep(0.1) 178 | except Exception as e: 179 | printf(f'抢奶异常:{str(e)}') 180 | break 181 | else: 182 | printf("等待开始...") 183 | time.sleep(0.1) 184 | os.system('pause') 185 | 186 | 187 | --------------------------------------------------------------------------------