commit
a4b10b13a8
14 changed files with 1019 additions and 0 deletions
@ -0,0 +1,70 @@ |
|||
import warnings |
|||
|
|||
import time |
|||
from datetime import datetime |
|||
|
|||
import requests.utils |
|||
|
|||
from jdseckillAPIv2 import JDSecKillAPI |
|||
from tools.mylogger import logger |
|||
|
|||
warnings.filterwarnings('ignore') |
|||
from concurrent.futures import ThreadPoolExecutor, wait |
|||
|
|||
|
|||
class JDSecKillSubmit(JDSecKillAPI): |
|||
|
|||
def __init__(self, sku, ck): |
|||
super().__init__(sku=sku, ck=ck) |
|||
self.sku = sku |
|||
self.ck = ck |
|||
|
|||
def log(self, str_p): |
|||
logger.info(str_p) |
|||
|
|||
def doKill(self, sk, order_data): |
|||
resp_json = self.submit_order(order_data=order_data, sk=sk) |
|||
if resp_json is not None: |
|||
txt = order_data['address']['name'] + "抢购结果:" + str(resp_json) |
|||
self.log(txt) |
|||
if resp_json['success']: |
|||
self.send_message(order_data['address']['name'] + '抢购成功, 订单:' + str(resp_json)) |
|||
|
|||
def appoint_task(self): |
|||
try: |
|||
resp_json = self.appoint_sku() |
|||
print("预约结果:%s" % str(resp_json)) |
|||
self.log('appoint:' + str(resp_json)) |
|||
except Exception as e: |
|||
print(str(e)) |
|||
|
|||
def killSku(self): |
|||
|
|||
try: |
|||
token_params = self.get_token_key() |
|||
print(datetime.now()) |
|||
divide_url = self.get_appjmp(token_params=token_params) |
|||
print(datetime.now()) |
|||
captcha_url = self.get_divide(divide_url=divide_url) |
|||
print(datetime.now()) |
|||
seckill_url = self.get_captcha(captcha_url=captcha_url) |
|||
print(datetime.now()) |
|||
|
|||
# todo 测试url |
|||
# seckill_url = 'https://marathon.jd.com/seckillM/seckill.action?skuId=' + self.sku + '&num=1&rid=1639830212' |
|||
resp = self.visit_seckill(seckill_url=seckill_url) |
|||
|
|||
order_data = self.init_action() |
|||
print(datetime.now()) |
|||
if order_data is not None: |
|||
for k in range(50): |
|||
sk_val = self.get_tak() |
|||
print("计算sk:%s" % str(sk_val)) |
|||
self.doKill(sk_val, order_data) |
|||
time.sleep(0.5) |
|||
return True |
|||
|
|||
return False |
|||
except Exception as e: |
|||
print(str(e)) |
|||
return False |
@ -0,0 +1,52 @@ |
|||
import json |
|||
import time |
|||
|
|||
import requests |
|||
|
|||
|
|||
class JDTimer: |
|||
|
|||
def __init__(self): |
|||
self.headers = { |
|||
'user-agent': 'okhttp/3.12.1;jdmall;android;version/10.5.0;build/95837;', |
|||
'content-type': 'application/x-www-form-urlencoded', |
|||
} |
|||
self.session = requests.Session() |
|||
try: |
|||
self.jd_time() |
|||
except Exception as e: |
|||
print(e) |
|||
|
|||
def jd_time(self): |
|||
""" |
|||
从京东服务器获取时间毫秒 |
|||
:return: |
|||
""" |
|||
url = 'https://api.m.jd.com/client.action?functionId=queryMaterialProducts&client=wh5' |
|||
ret = self.session.get(url, headers=self.headers, allow_redirects=False, verify=False).text |
|||
js = json.loads(ret) |
|||
|
|||
return int(js["currentTime2"]) |
|||
|
|||
def local_time(self): |
|||
""" |
|||
获取本地毫秒时间 |
|||
:return: |
|||
""" |
|||
return int(round(time.time() * 1000)) |
|||
|
|||
def local_jd_time_diff(self): |
|||
""" |
|||
计算本地与京东服务器时间差 |
|||
:return: |
|||
""" |
|||
try: |
|||
return self.local_time() - self.jd_time() |
|||
except Exception as e: |
|||
print(e) |
|||
return 0 |
|||
|
|||
if __name__ == '__main__': |
|||
jdtimer = JDTimer() |
|||
for i in range(5): |
|||
print(jdtimer.local_jd_time_diff()) |
@ -0,0 +1,75 @@ |
|||
import time |
|||
import sys |
|||
import os |
|||
|
|||
|
|||
curPath = os.path.abspath(os.path.dirname(__file__)) |
|||
rootPath = os.path.split(curPath)[0] |
|||
sys.path.append(rootPath) |
|||
|
|||
from api_timer import JDTimer |
|||
from tools import utils |
|||
from JDMain import JDSecKillSubmit |
|||
from tools.mylogger import logger |
|||
|
|||
|
|||
class JD: |
|||
|
|||
def __init__(self): |
|||
sku = '100012043978' |
|||
|
|||
def log(self, str_p): |
|||
logger.info(str_p) |
|||
|
|||
def yuyueSku(self, sku, ck): |
|||
self.jdapi = JDSecKillSubmit(sku, ck) |
|||
self.jdapi.appoint_task() |
|||
|
|||
def killSku(self): |
|||
for i in range(5): |
|||
print('第%d次kill---------------------------->' % i) |
|||
result = self.jdapi.killSku() |
|||
if result: |
|||
break |
|||
|
|||
def syncTime(self): |
|||
jdTimer = JDTimer() |
|||
return jdTimer.local_jd_time_diff() |
|||
|
|||
|
|||
if __name__ == '__main__': |
|||
|
|||
jd = JD() |
|||
jd.log("正在读取cookie") |
|||
file = open("cookie-xqs.txt") |
|||
ck = file.read() |
|||
ck = 'pin=jd_694172ad51580;wskey=AAJgfXWSAEBLNQvLpLSYBYcBCqSXPF0LSFJksN9TUW-zjHxTQzDHotSD_LUE5EqkKLhBT3r0b3jCYYm33xg21oLFXWdad7mG;whwswswws=ypBVaXEwFjiJxh/kEB/6O2f6fohXOoCM3D8YNlQLR9tc=;unionwsws={"devicefinger":"eidA852c81205asb09A7r2HGTjCoC1RNl7MXytPQPScu2F6yVo+5IRMfDrQg8oI21UoEA0ZlhW+EgFWItSqxk76gpd5LLB389Tk1jXNw+GmMO1H7tOt5","jmafinger":"ypBVaXEwFjiJxh\/kEB\/6O2f6fohXOoCM3D8YNlQLR9tc="};' |
|||
jd.log(ck) |
|||
|
|||
sku = '100012043978' |
|||
killTime = '2022-09-24 11:59:59.900' |
|||
killTimeTs = utils.getTimeStamp(killTime, format='%Y-%m-%d %H:%M:%S.%f') |
|||
|
|||
syncedTime = False |
|||
hasYuyue = False |
|||
|
|||
timeDiff = 0 # 时差 |
|||
|
|||
while True: |
|||
nowTimeTs = int(time.time() * 1000) |
|||
killDiff = killTimeTs - nowTimeTs |
|||
print("时间剩余%s秒" % str(int(killDiff / 1000))) |
|||
|
|||
if killDiff < 5 * 60 * 1000 and not syncedTime: |
|||
syncedTime = True |
|||
timeDiff = jd.syncTime() |
|||
print("时差:%s" % str(timeDiff)) |
|||
killTimeTs = killTimeTs + timeDiff |
|||
elif killDiff < 1 * 60 * 1000 and not hasYuyue: |
|||
hasYuyue = True |
|||
jd.yuyueSku(sku=sku, ck=ck) |
|||
elif killDiff < 0: |
|||
print("时差:%s" % str(timeDiff)) |
|||
jd.killSku() |
|||
break |
|||
time.sleep(0.01) |
@ -0,0 +1 @@ |
|||
pin=jd_41d74c83f8224;wskey=AAJjKGIcAED51MS4xl3rMhkuKoz3aIdtHgYbbY_gONAtDcvoXgp0nCjPWKcjgXoBw3ZNcm-HVECeryK5NBFQiErqyGbAcqt-;whwswswws=JD012145b9WBZ52FxcoJ166359098310502j1UGQOp_xw1sHnZf2TBLxIAVcI1pr_ptSG7GbI4Jh8JHPzpgXIVd6vHgcp4KUP7bIcL92ot4SobMNdIjsb6CeO0xXfdGg1DB166dh3n~lV6zvij0xVW8O87RwFvqyq8bfocRq2uG0yIAc6GJfPzG3Vt7W-bSkl68yzw3cggRUZpEKUJ0VpkW0x0Q0aGrCFLasnWujHANJMp2D1tUHzbtF-NKQkCBUiGE1ZKdTwYkeVoNQaOoU87ivURTKramyPzaIW67BRI6kPNkr3PLHsHc;unionwsws={"devicefinger":"eidAfa90812247s5vgf0CkxeRgeWBZfWowyK9r4H9Y2h1wPWRDa\/+LyYAJea3ooTv4ePNmFFv1ZArvKR74Nk1rlZWoaTpHUgZCeqmC5Lix6Hz1eGUEN6","jmafinger":"JD012145b9WBZ52FxcoJ166359098310502j1UGQOp_xw1sHnZf2TBLxIAVcI1pr_ptSG7GbI4Jh8JHPzpgXIVd6vHgcp4KUP7bIcL92ot4SobMNdIjsb6CeO0xXfdGg1DB166dh3n~lV6zvij0xVW8O87RwFvqyq8bfocRq2uG0yIAc6GJfPzG3Vt7W-bSkl68yzw3cggRUZpEKUJ0VpkW0x0Q0aGrCFLasnWujHANJMp2D1tUHzbtF-NKQkCBUiGE1ZKdTwYkeVoNQaOoU87ivURTKramyPzaIW67BRI6kPNkr3PLHsHc"}; |
@ -0,0 +1,350 @@ |
|||
import json |
|||
import warnings |
|||
|
|||
import requests |
|||
import re |
|||
from urllib import parse |
|||
import time |
|||
|
|||
from wxpusher import WxPusher |
|||
|
|||
from tools import utils |
|||
from tools.jd_sign import getSign |
|||
|
|||
warnings.filterwarnings('ignore') |
|||
|
|||
|
|||
def getUrlParams(url): |
|||
res = dict(parse.parse_qsl(url)) |
|||
return res |
|||
|
|||
|
|||
def get_cookie_string(cookie): |
|||
cookie_string = '' |
|||
for cookie_key in cookie.keys(): |
|||
cookie_string += '%s=%s;' % (cookie_key, cookie[cookie_key]) |
|||
return cookie_string |
|||
|
|||
|
|||
def get_jd_time(): |
|||
response = requests.get(url='https://api.m.jd.com/client.action?functionId=queryMaterialProducts&client=wh5') |
|||
print(response.json()) |
|||
|
|||
|
|||
def get_sk(data): |
|||
data_val = [val for val in data['data'].values()] |
|||
n, o, p, q, r, s = data_val[0], data_val[1], data_val[2], data_val[3], data_val[4], data_val[5] |
|||
sk_val = '' |
|||
if n == 'cca': |
|||
sk_val = p[14:19].lower() + o[5:15].upper() |
|||
if n == 'ab': # check ok |
|||
sk_val = r[10:18] + s[2:13].lower() |
|||
if n == 'ch': |
|||
sk_val = q.upper() + r[6:10].upper() |
|||
if n == 'cbc': # check ok |
|||
sk_val = q[3:13].upper() + p[10:19].lower() |
|||
if n == 'by': |
|||
sk_val = o[5:8] + re.sub('a', 'c', p, flags=re.IGNORECASE) |
|||
if n == 'xa': |
|||
sk_val = o[1:16] + s[4:10] |
|||
if n == 'cza': |
|||
sk_val = q[6:19].lower() + s[5:11] |
|||
if n == 'cb': |
|||
sk_val = s[5:14] + p[2:13].upper() |
|||
|
|||
return sk_val |
|||
|
|||
|
|||
class JDSecKillAPI: |
|||
def __init__(self, sku, ck): |
|||
self.skuId = sku |
|||
self.s = requests.session() |
|||
self.sku = sku |
|||
self.ck = ck |
|||
self.aid = '' |
|||
self.eid = 'eidAccfa8121das3mOM5swaGRcSw7E22kO50H5jjOzSUZLdxjWFZLi3ATsvj875K/RWM0W4ztxrbes6TNeio5uhWCeJIKObRbFo6NaYRyMqYuMJ2MM5D' |
|||
self.uuid = '351792042184702-6dd3f46ae26a' |
|||
self.uts = '0f31TVRjBSsqndu4/jgUPz6uymy50MQJAUhDDPnNIByQiRdjk5SK6CXmdShdxGaPRUd2+o8JNufp2fsgzyZpKhao+6lXsd3TXF8+jFmN/08eWFOjD36AXn3DPYPoc8MKL9ccf40wpTgO1wSP1oliin/fcMzzPHSxzINfo/svdCXHzPsMY3eZLWP0KGqPLr5fXA1RZRoBs4xl/IYv7E80OQ==' |
|||
self.wifiBssid = '' |
|||
self.ua = 'AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.106 Mobile Safari/537.36' |
|||
|
|||
def appoint_sku(self): |
|||
headers = { |
|||
'user-agent': 'okhttp/3.12.1;jdmall;android;version/10.5.0;build/95837;', |
|||
'content-type': 'application/x-www-form-urlencoded', |
|||
'cookie': self.ck, |
|||
'jdc-backup': self.ck, |
|||
} |
|||
|
|||
ts = int(time.time() * 1000) |
|||
uuid = self.uuid |
|||
ep = utils.get_ep(ts, uuid) |
|||
|
|||
query_params = { |
|||
'functionId': 'appoint', |
|||
'clientVersion': '10.5.0', |
|||
'build': '95837', |
|||
'client': 'android', |
|||
'd_brand': 'HUAWEI', |
|||
'd_model': 'LIO-AN00', |
|||
'osVersion': '7.1.2', |
|||
'screen': '1920*1080', |
|||
'partner': 'hhqj02', |
|||
'aid': self.aid, |
|||
'eid': self.eid, |
|||
'sdkVersion': '29', |
|||
'lang': 'zh_CN', |
|||
'harmonyOs': '0', |
|||
'uuid': self.uuid, |
|||
'area': '', |
|||
'networkType': 'wifi', |
|||
'wifiBssid': self.wifiBssid, |
|||
'uts': self.uts, |
|||
'uemps': '0-0', |
|||
'ext': '{"prstate":"0","pvcStu":"1"}', |
|||
'ef': '1', |
|||
'ep': json.dumps(ep, ensure_ascii=False, separators=(',', ':')), |
|||
} |
|||
reserve_url = 'https://api.m.jd.com/client.action' |
|||
|
|||
body = {"autoAddCart": "0", "bsid": "", "check": "0", "ctext": "", "isShowCode": "0", "mad": "0", |
|||
"skuId": self.skuId, "type": "1"} |
|||
|
|||
plainTextDic = { |
|||
"st": ts, # 毫秒级时间戳 |
|||
"sv": "120", |
|||
"functionId": query_params['functionId'], |
|||
"uuid": uuid, |
|||
"client": query_params['client'], |
|||
"clientVersion": query_params['clientVersion'], |
|||
"body": json.dumps(body, ensure_ascii=False, separators=(',', ':')) |
|||
} |
|||
st, sign, sv = getSign(plainTextDic) |
|||
|
|||
query_params.update(st=st) |
|||
query_params.update(sign=sign) |
|||
query_params.update(sv=sv) |
|||
|
|||
data = {'body': json.dumps(body, ensure_ascii=False, separators=(',', ':'))} |
|||
|
|||
response = self.s.post(url=reserve_url, |
|||
params=query_params, |
|||
data=data, |
|||
headers=headers, |
|||
allow_redirects=False, |
|||
verify=False, |
|||
timeout=3) |
|||
return response.json() |
|||
|
|||
def get_token_key(self): |
|||
headers = { |
|||
'user-agent': 'okhttp/3.12.1;jdmall;android;version/10.5.0;build/95837;', |
|||
'content-type': 'application/x-www-form-urlencoded', |
|||
'cookie': self.ck, |
|||
'jdc-backup': self.ck, |
|||
} |
|||
|
|||
ts = int(time.time() * 1000) |
|||
uuid = self.uuid |
|||
ep = utils.get_ep(ts, uuid) |
|||
|
|||
query_params = { |
|||
'functionId': 'genToken', |
|||
'clientVersion': '10.5.0', |
|||
'build': '95837', |
|||
'client': 'android', |
|||
'd_brand': 'HUAWEI', |
|||
'd_model': 'LIO-AN00', |
|||
'osVersion': '7.1.2', |
|||
'screen': '1920*1080', |
|||
'partner': 'hhqj02', |
|||
'aid': self.aid, |
|||
'eid': self.eid, |
|||
'sdkVersion': '29', |
|||
'lang': 'zh_CN', |
|||
'harmonyOs': '0', |
|||
'uuid': self.uuid, |
|||
'area': '', |
|||
'networkType': 'wifi', |
|||
'wifiBssid': self.wifiBssid, |
|||
'uts': self.uts, |
|||
'uemps': '0-0', |
|||
'ext': '{"prstate":"0","pvcStu":"1"}', |
|||
'ef': '1', |
|||
'ep': json.dumps(ep, ensure_ascii=False, separators=(',', ':')), |
|||
} |
|||
|
|||
body = {"action": "to", "to": "https://divide.jd.com/user_routing?skuId="+self.sku} |
|||
|
|||
plainTextDic = { |
|||
"st": ts, # 毫秒级时间戳 |
|||
"sv": "120", |
|||
"functionId": query_params['functionId'], |
|||
"uuid": uuid, |
|||
"client": query_params['client'], |
|||
"clientVersion": query_params['clientVersion'], |
|||
"body": json.dumps(body, ensure_ascii=False, separators=(',', ':')) |
|||
} |
|||
st, sign, sv = getSign(plainTextDic) |
|||
|
|||
query_params.update(st=st) |
|||
query_params.update(sign=sign) |
|||
query_params.update(sv=sv) |
|||
|
|||
data = {'body': json.dumps(body, ensure_ascii=False, separators=(',', ':'))} |
|||
|
|||
response = self.s.post(url='https://api.m.jd.com/client.action', |
|||
params=query_params, |
|||
data=data, |
|||
headers=headers, |
|||
allow_redirects=False, |
|||
verify=False, |
|||
timeout=3) |
|||
# token_key = response.json()['tokenKey'] |
|||
# print('Token Key: ----------> %s' % response.json()) |
|||
# print(response.status_code) |
|||
json_obj = response.json() |
|||
print('Get genToken--------------->%s' % str(json_obj)) |
|||
return json_obj |
|||
|
|||
def get_appjmp(self, token_params): |
|||
headers = { |
|||
'user-agent': self.ua |
|||
} |
|||
appjmp_url = token_params['url'] |
|||
params = { |
|||
'to': 'https://divide.jd.com/user_routing?skuId=%s' % self.skuId, |
|||
'tokenKey': token_params['tokenKey'] |
|||
} |
|||
|
|||
response = self.s.get(url=appjmp_url, params=params, allow_redirects=False, verify=False, headers=headers) |
|||
print('Get Appjmp跳转链接-------------->%s' % response.headers['Location']) |
|||
return response.headers['Location'] |
|||
|
|||
def get_divide(self, divide_url): |
|||
headers = { |
|||
'user-agent': self.ua |
|||
} |
|||
response = self.s.get(url=divide_url, allow_redirects=False, verify=False, headers=headers) |
|||
print('Get Divide跳转链接-------------->%s' % response.headers['Location']) |
|||
return response.headers['Location'] |
|||
|
|||
def get_captcha(self, captcha_url): |
|||
headers = { |
|||
'user-agent': self.ua |
|||
} |
|||
response = self.s.get(url=captcha_url, allow_redirects=False, verify=False, headers=headers) |
|||
print('Get Captcha跳转链接-------------->%s' % response.headers['Location']) |
|||
return response.headers['Location'] |
|||
|
|||
def visit_seckill(self, seckill_url): |
|||
headers = { |
|||
'user-agent': self.ua |
|||
} |
|||
response = self.s.get(url=seckill_url, allow_redirects=False, verify=False, headers=headers) |
|||
return response |
|||
|
|||
def init_action(self, num=1): |
|||
|
|||
try: |
|||
headers = { |
|||
'user-agent': self.ua, |
|||
'Connection': 'keep-alive' |
|||
} |
|||
init_action_url = 'https://marathon.jd.com/seckillnew/orderService/init.action' |
|||
data = { |
|||
'sku': self.skuId, |
|||
'num': num, |
|||
'id': 0, |
|||
'provinceId': 0, |
|||
'cityId': 0, |
|||
'countyId': 0, |
|||
'townId': 0, |
|||
} |
|||
response = self.s.post(url=init_action_url, data=data, allow_redirects=False, verify=False, headers=headers) |
|||
print('init action返回数据:%s' % response.text) |
|||
return response.json() |
|||
except Exception as e: |
|||
print(str(e)) |
|||
return None |
|||
|
|||
|
|||
def get_tak(self): |
|||
try: |
|||
headers = { |
|||
'user-agent': self.ua, |
|||
'Connection': 'keep-alive' |
|||
} |
|||
tak_url = 'https://tak.jd.com/t/871A9?_t=%d' % (int(round(time.time() * 1000))) |
|||
response = self.s.get(url=tak_url, allow_redirects=False, verify=False, headers=headers) |
|||
sk_val = get_sk(data=response.json()) |
|||
return sk_val |
|||
except Exception as e: |
|||
print(str(e)) |
|||
return '' |
|||
|
|||
def submit_order(self, order_data, sk): |
|||
try: |
|||
headers = { |
|||
'user-agent': self.ua, |
|||
'Connection': 'keep-alive' |
|||
} |
|||
submit_order_url = 'https://marathon.jd.com/seckillnew/orderService/submitOrder.action?skuId=%s' % self.skuId |
|||
address_info = order_data['address'] |
|||
invoice_info = order_data['invoiceInfo'] |
|||
data = { |
|||
'num': order_data['seckillSkuVO']['num'], |
|||
'addressId': address_info['id'], |
|||
'yuShou': True, |
|||
'isModifyAddress': False, |
|||
'name': address_info['name'], |
|||
'provinceId': address_info['provinceId'], |
|||
'provinceName': address_info['provinceName'], |
|||
'cityId': address_info['cityId'], |
|||
'cityName': address_info['cityName'], |
|||
'countyId': address_info['countyId'], |
|||
'countyName': address_info['countyName'], |
|||
'townId': address_info['townId'], |
|||
'townName': address_info['townName'], |
|||
'addressDetail': address_info['addressDetail'], |
|||
'mobile': address_info['mobile'], |
|||
'mobileKey': address_info['mobileKey'], |
|||
'email': '', |
|||
'invoiceTitle': invoice_info['invoiceTitle'], |
|||
'invoiceContent': invoice_info['invoiceContentType'], |
|||
'invoicePhone': invoice_info['invoicePhone'], |
|||
'invoicePhoneKey': invoice_info['invoicePhoneKey'], |
|||
'invoice': True, |
|||
'codTimeType': '3', |
|||
'paymentType': '4', |
|||
'overseas': '0', |
|||
'token': order_data['token'], |
|||
'sk': sk, |
|||
} |
|||
|
|||
response = self.s.post(url=submit_order_url, data=data, allow_redirects=False, verify=False, headers=headers) |
|||
return response.json() |
|||
except Exception as e: |
|||
print('submit error--->') |
|||
return None |
|||
|
|||
def send_message(self, content): |
|||
try: |
|||
# 推送token |
|||
PUSH_TOKEN = 'AT_4XxUFvSjSLWTlFhX1nFmIepe1RNoGq8b' |
|||
|
|||
UIDS = [ |
|||
'UID_D77yyDO0pT7K0f1q2UijDTGnGthF', |
|||
] |
|||
msg = WxPusher.send_message(content, |
|||
uids=UIDS, |
|||
token=PUSH_TOKEN) |
|||
except Exception as e: |
|||
print('send_message error--->'+str(e)) |
|||
|
|||
if __name__ == '__main__': |
|||
ck = 'pin=jd_694172ad51580;wskey=AAJgfXWSAEBLNQvLpLSYBYcBCqSXPF0LSFJksN9TUW-zjHxTQzDHotSD_LUE5EqkKLhBT3r0b3jCYYm33xg21oLFXWdad7mG;whwswswws=ypBVaXEwFjiJxh/kEB/6O2f6fohXOoCM3D8YNlQLR9tc=;unionwsws={"devicefinger":"eidA852c81205asb09A7r2HGTjCoC1RNl7MXytPQPScu2F6yVo+5IRMfDrQg8oI21UoEA0ZlhW+EgFWItSqxk76gpd5LLB389Tk1jXNw+GmMO1H7tOt5","jmafinger":"ypBVaXEwFjiJxh\/kEB\/6O2f6fohXOoCM3D8YNlQLR9tc="};' |
|||
ck = 'pin=jd_4d36cfba7dab3;wskey=AAJjGfg2AEDbVEKTmVkgEvWx-McNVFq980fU5IHeej0nLaHVNdOtzlTLYBDCEucWGJ4G9teOfEzntfRGd6KQyjXgY3rjDDn1;whwswswws=JD012145b9v1fE5xpOyD1662646298263061cDoZzexYxAp8KLqT9smx6eCUAMi_vgpfvlNGugBkHqboOLvPxFIIgdchS83Af4aCPkH9MZR8ybX3QlO52r5tGF45M9TrieypOzwu3NAoOs0a40rty~w8wI98OE8okFESgoJ3sI8KD1kO1fXEYyQfW7eDyRLBI1VlbD72BRZvaIwvqX8mX245w7Jl7eI9mR2U_2IrtbtCm-NOZyDZr7LWiepMRuTaaO-iRDLr0M_4xyeRgstrh1ombJE27yWpzAQs4PLrFSWhVWGnPf597V0y6FJhG3YaXA;unionwsws={"devicefinger":"eidAea1681212dsbM9nriXryQHq\/kLPLj0nYnTPZ7QyYY2ofy15o7Ohj1DMrIY\/71NnUV3ow\/8dwlD\/hgR5tfjQJNif\/1NbGABbd9A29YETZGl0TuF45","jmafinger":"JD012145b9v1fE5xpOyD1662646298263061cDoZzexYxAp8KLqT9smx6eCUAMi_vgpfvlNGugBkHqboOLvPxFIIgdchS83Af4aCPkH9MZR8ybX3QlO52r5tGF45M9TrieypOzwu3NAoOs0a40rty~w8wI98OE8okFESgoJ3sI8KD1kO1fXEYyQfW7eDyRLBI1VlbD72BRZvaIwvqX8mX245w7Jl7eI9mR2U_2IrtbtCm-NOZyDZr7LWiepMRuTaaO-iRDLr0M_4xyeRgstrh1ombJE27yWpzAQs4PLrFSWhVWGnPf597V0y6FJhG3YaXA"};' |
|||
jdapi = JDSecKillAPI('100012043978', ck) |
|||
print('预约结果--->', jdapi.appoint_sku()) |
|||
print('gentoken结果--->', jdapi.get_token_key('100012043978')) |
@ -0,0 +1,81 @@ |
|||
import time |
|||
import sys |
|||
import os |
|||
curPath = os.path.abspath(os.path.dirname(__file__)) |
|||
rootPath = os.path.split(curPath)[0] |
|||
sys.path.append(rootPath) |
|||
|
|||
from multiprocessing import Process |
|||
import requests |
|||
|
|||
from tools import utils |
|||
from JDMain import JDSecKillSubmit |
|||
from api_timer import JDTimer |
|||
|
|||
|
|||
|
|||
def syncTime(): |
|||
jdTimer = JDTimer() |
|||
return jdTimer.local_jd_time_diff() |
|||
|
|||
|
|||
def yuyueSku(sku, ck): |
|||
jdapi = JDSecKillSubmit(sku, ck) |
|||
jdapi.appoint_task() |
|||
|
|||
|
|||
def killSku(sku, ck): |
|||
jdapi = JDSecKillSubmit(sku, ck) |
|||
for i in range(5): |
|||
print('第%d次kill---------------------------->' % i) |
|||
if jdapi.killSku(): |
|||
break |
|||
|
|||
def work(killTime, ck): |
|||
print('ck:', ck) |
|||
sku = '100012043978' |
|||
killTimeTs = utils.getTimeStamp(killTime, format='%Y-%m-%d %H:%M:%S.%f') |
|||
|
|||
syncedTime = False |
|||
hasYuyue = False |
|||
|
|||
timeDiff = 0 # 时差 |
|||
|
|||
while True: |
|||
nowTimeTs = int(time.time() * 1000) |
|||
killDiff = killTimeTs - nowTimeTs |
|||
print("时间剩余%s秒" % str(int(killDiff / 1000))) |
|||
|
|||
if killDiff < 5 * 60 * 1000 and not syncedTime: |
|||
syncedTime = True |
|||
timeDiff = syncTime() |
|||
print("时差:%s" % str(timeDiff)) |
|||
killTimeTs = killTimeTs + timeDiff |
|||
elif killDiff < 2 * 60 * 1000 and not hasYuyue: |
|||
hasYuyue = True |
|||
yuyueSku(sku=sku, ck=ck) |
|||
elif killDiff < 0: |
|||
print("时差:%s" % str(timeDiff)) |
|||
killSku(sku=sku, ck=ck) |
|||
break |
|||
time.sleep(0.01) |
|||
|
|||
|
|||
if __name__ == '__main__': |
|||
|
|||
# 抢购时间 |
|||
killTime = '2022-11-09 11:59:59.800' |
|||
|
|||
# cookie |
|||
cks = [ |
|||
'pin=jd_41d74c83f8224;wskey=AAJjKGIcAED51MS4xl3rMhkuKoz3aIdtHgYbbY_gONAtDcvoXgp0nCjPWKcjgXoBw3ZNcm-HVECeryK5NBFQiErqyGbAcqt-;whwswswws=JD012145b9WBZ52FxcoJ166359098310502j1UGQOp_xw1sHnZf2TBLxIAVcI1pr_ptSG7GbI4Jh8JHPzpgXIVd6vHgcp4KUP7bIcL92ot4SobMNdIjsb6CeO0xXfdGg1DB166dh3n~lV6zvij0xVW8O87RwFvqyq8bfocRq2uG0yIAc6GJfPzG3Vt7W-bSkl68yzw3cggRUZpEKUJ0VpkW0x0Q0aGrCFLasnWujHANJMp2D1tUHzbtF-NKQkCBUiGE1ZKdTwYkeVoNQaOoU87ivURTKramyPzaIW67BRI6kPNkr3PLHsHc;unionwsws={"devicefinger":"eidAfa90812247s5vgf0CkxeRgeWBZfWowyK9r4H9Y2h1wPWRDa\/+LyYAJea3ooTv4ePNmFFv1ZArvKR74Nk1rlZWoaTpHUgZCeqmC5Lix6Hz1eGUEN6","jmafinger":"JD012145b9WBZ52FxcoJ166359098310502j1UGQOp_xw1sHnZf2TBLxIAVcI1pr_ptSG7GbI4Jh8JHPzpgXIVd6vHgcp4KUP7bIcL92ot4SobMNdIjsb6CeO0xXfdGg1DB166dh3n~lV6zvij0xVW8O87RwFvqyq8bfocRq2uG0yIAc6GJfPzG3Vt7W-bSkl68yzw3cggRUZpEKUJ0VpkW0x0Q0aGrCFLasnWujHANJMp2D1tUHzbtF-NKQkCBUiGE1ZKdTwYkeVoNQaOoU87ivURTKramyPzaIW67BRI6kPNkr3PLHsHc"};', |
|||
] |
|||
|
|||
p = [] |
|||
for i in range(len(cks)): |
|||
p1 = Process(target=work, args=(killTime, cks[i],)) |
|||
p1.start() |
|||
p.append(p1) |
|||
|
|||
for i in range(len(cks)): |
|||
p[i].join() |
@ -0,0 +1,3 @@ |
|||
requests==2.27.1 |
|||
wxpusher==2.2.0 |
|||
urllib3==1.26.9 |
@ -0,0 +1,30 @@ |
|||
计算sk:zr7oflx9p335iWYurie |
|||
Expecting value: line 1 column 1 (char 0) |
|||
Get Divide跳转链接-------------->https://marathon.jd.com/m/captcha.html?sid=b8385a800e93b184ff8bb16a0e79d8aw&skuId=10001 |
|||
2043978&mid=rvXgpdduG3wnlgfPzI2wXkvpgNqF4IA9qcWds4ffipY |
|||
Get Captcha跳转链接-------------->https://marathon.jd.com/mobile/koFail.html |
|||
init action返回数据:{"address":{"addressDetail":"西李村","areaCode":"999999","cityId":2900,"cityName":"济宁市","countyI |
|||
d":2917,"countyName":"金乡县","defaultAddress":false,"id":6188735630,"mobile":"133****4689","mobileKey":"f7dcf949de1a7b4 |
|||
27463a9dd90f632e1","name":"王秋娟","overseas":0,"phone":"","postCode":"","provinceId":13,"provinceName":"山东","selected |
|||
":true,"townId":25860,"townName":"鱼山街道","yuyueAddress":false},"buyNum":2,"code":"200","invoiceInfo":{"invoiceContent |
|||
Type":1,"invoicePhone":"133****4689","invoicePhoneKey":"f7dcf949de1a7b427463a9dd90f632e1","invoiceTitle":4,"invoiceType" |
|||
:3},"jingdouBO":{"canUseCount":0,"forbidUseJingdou":false,"jingdouDiscount":0,"jingdouSteps":[],"pointsDeductionRate":50 |
|||
,"rate":100,"totalCount":179,"usedCount":0},"orderPriceBO":{"couponAbleNum":0,"couponDiscount":0.00,"couponDiscountTotal |
|||
":0.00,"couponSelectNum":0,"couponTypeList":[],"freight":0.00,"giftCardAbleNum":0,"giftCardDiscount":0.00,"giftCardSelec |
|||
tNum":0,"jingdouDiscount":0,"manjianDiscount":0.00,"orderTax":0.00,"productTotalPrice":1499.00,"redPacketDeductionAmount |
|||
":0,"redPacketIsSelected":false,"redPacketTotalAmount":0,"showXuZhongInfo":false,"totalPrice":1499.00,"weight":"1.12","y |
|||
unfeiDiscount":0.00},"payment":{"paymentId":4,"paymentName":"在线支付"},"preSaleBO":{"hidePrice":false,"refundDeposit":f |
|||
alse},"seckillOrderExt":{},"seckillSkuVO":{"color":"飞天 53%vol 500ml 贵州茅台酒","extMap":{"YuShou":"1","is7ToReturn":" |
|||
0","new7ToReturn":"8","thwa":"0","SoldOversea":"0"},"height":0.0,"jdPrice":1499.00,"length":0.0,"num":1,"rePrice":0.00," |
|||
size":"","skuId":100012043978,"skuImgUrl":"jfs/t1/204850/31/20522/123067/61af3d74E747493f0/385d705a66b5263b.jpg","skuNam |
|||
e":"飞天 53%vol 500ml 贵州茅台酒(带杯)","skuPrice":1499.00,"thirdCategoryId":0.0,"venderName":"京东自营","venderType" |
|||
:0,"weight":1.120,"width":0.0},"shipment":{"bundleUuid":"BundleRelation_1125395520593502208","obtainAllCombinationBundle |
|||
":"CombinationBundleRelation_1125395520425730051","obtainOrder":"-1719262869","shipmentTimeType":4,"shipmentTimeTypeName |
|||
":"标准达","shipmentType":65,"shipmentTypeName":"京东配送","uuid":"101612_1125395520610279424"},"token":"fdc90dde774b3c5 |
|||
84b613a8b33050a95","userInfoBO":{"userScore":5525}} |
|||
计算sk:6ktun1kxw1gypV4GMMQ |
|||
抢购结果:{'appUrl': 'https://mpay.m.jd.com/mpay.1ec8f70280318a51e2bb.html?appId=jd_m_msha&payId=3420cb4f0d7a4424b53f8ae7 |
|||
81f542f6', 'orderId': 250387144183, 'pcUrl': '//sko.jd.com/success/success.action?orderId=250387144183&rid=0.88556282118 |
|||
81714', 'resultCode': 0, 'skuId': 0, 'success': True, 'totalMoney': '1499.00'} |
|||
耗时:941 |
|||
Get Divide跳转链接-------------->https://marathon.jd.com/m/captcha.html?sid=b8385a800e93b184ff8bb16a0e79d8aw&skuId=10001 |
@ -0,0 +1,112 @@ |
|||
# -*- coding: utf-8 -*- |
|||
class ModifiedBase64(object): |
|||
|
|||
def __init__(self): |
|||
self.aae = ['K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', |
|||
'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', |
|||
'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', |
|||
'8', '9', '+', '/'] |
|||
self.aaf = [None] * 128 |
|||
|
|||
# renamed from: pf |
|||
# def m23208pf(self): |
|||
i = 0 |
|||
i2 = 0 |
|||
while True: |
|||
bArr = self.aaf |
|||
if i2 <= len(bArr) - 1: |
|||
bArr[i2] = -1 |
|||
i2 += 1 |
|||
else: |
|||
break |
|||
while True: |
|||
cArr = self.aae |
|||
if i <= len(cArr) - 1: |
|||
self.aaf[ord(cArr[i])] = int(i) |
|||
i += 1 |
|||
else: |
|||
return |
|||
|
|||
def m23207r(self, str_): |
|||
result = '' |
|||
bArr = bytearray(str_.encode('utf-8')) |
|||
|
|||
i = 0 |
|||
while i <= len(bArr) - 1: |
|||
bArr2 = [None] * 4 |
|||
b = 0 |
|||
i2 = 0 |
|||
while i2 <= 2: |
|||
i3 = i + i2 |
|||
if i3 <= len(bArr) - 1: |
|||
bArr2[i2] = (b | ((bArr[i3] & 255) >> ((i2 * 2) + 2))) |
|||
b = ((((bArr[i3] & 255) << (((2 - i2) * 2) + 2)) & 255) >> 2) |
|||
else: |
|||
bArr2[i2] = b |
|||
b = 0x40 # SignedBytes.MAX_POWER_OF_TWO; |
|||
i2 += 1 |
|||
bArr2[3] = b |
|||
|
|||
i4 = 0 |
|||
while i4 <= 3: |
|||
if bArr2[i4] <= 63: |
|||
result = result + self.aae[bArr2[i4]] |
|||
else: |
|||
result = result + '=' |
|||
i4 += 1 |
|||
i += 3 |
|||
|
|||
return result |
|||
|
|||
# renamed from: eC |
|||
def m23209eC(self, str_): |
|||
""" generated source for method m23209eC """ |
|||
bys = [] |
|||
# bytes = str_.encode('utf-8') |
|||
bytes = bytearray(str_.encode('utf-8')) |
|||
# print(bytes) |
|||
bArr = [None] * len(bytes) |
|||
i = 0 |
|||
while i <= len(bytes) - 1: |
|||
bArr[i] = self.aaf[bytes[i]] |
|||
i += 1 |
|||
i2 = 0 |
|||
while i2 <= len(bArr) - 1: |
|||
bArr2 = [None] * 3 |
|||
i3 = 0 |
|||
i4 = 0 |
|||
i7 = 0 |
|||
while i4 <= 2: |
|||
i5 = i2 + i4 |
|||
i6 = i5 + 1 |
|||
if i6 <= len(bArr) and bArr[i6] >= 0: |
|||
bArr2[i4] = ((bArr[i5] & 255) << ((i4 * 2) + 2)) | ((bArr[i6] & 255) >> (((2 - (i4 + 1)) * 2) + 2)) |
|||
i3 += 1 |
|||
i4 += 1 |
|||
while i7 <= i3 - 1: |
|||
bys.append(self.py2ja(bArr2[i7])) |
|||
i7 += 1 |
|||
i2 += 4 |
|||
return bytearray(bys).decode('utf-8') |
|||
|
|||
def py2ja(self, arr: int): |
|||
""" |
|||
python字节数组转java字节数组 |
|||
:return: |
|||
""" |
|||
while arr >= 256: |
|||
arr = arr - 256 |
|||
return arr |
|||
|
|||
|
|||
if __name__ == '__main__': |
|||
# UUID = "ENYnDJO5CNGnCJC5DzcyBWHtEJK4ENcyDJu3EG==" |
|||
v = ModifiedBase64() |
|||
# a = v.m23209eC(UUID) |
|||
# print(a) |
|||
|
|||
text = '5ZIG5Ya26AQX6YQJ5YsY6SML5bsS' |
|||
print(v.m23209eC(text)) |
|||
|
|||
text = '唐冶街道刘老师' |
|||
print(v.m23207r(text)) |
@ -0,0 +1,51 @@ |
|||
import base64 |
|||
import hashlib |
|||
|
|||
|
|||
def getSign(params): |
|||
# sv传120 |
|||
key = [55, 146, 68, 104, 165, 61, 204, 127, 187, 15, 217, 136, 238, 154, 233, 90] |
|||
arg0 = [56, 48, 51, 48, 54, 102, 52, 51, 55, 48, 98, 51, 57, 102, 100, 53, 54, 51, 48, 97, 100, 48, 53, 50, 57, 102, |
|||
55, 55, 97, 100, 98, 54] |
|||
|
|||
sign = "functionId=" + params.get("functionId") + "&body=" + params.get("body") + "&uuid=" + params.get("uuid") \ |
|||
+ "&client=" + params.get("client") + "&clientVersion=" + params.get("clientVersion") + "&st=" + str( |
|||
params.get("st")) \ |
|||
+ "&sv=" + str(params.get("sv")) |
|||
arg2 = bytearray(sign, 'utf-8') |
|||
# print([x for x in arg2]) |
|||
ss = [None] * len(arg2) |
|||
for i in range(len(arg2)): |
|||
R0 = arg2[i] |
|||
R2 = key[i & 15] |
|||
R4 = arg0[i & 7] |
|||
R0 = ((R2 ^ R0) ^ R4) + R2 |
|||
R2 = (R2 ^ R0) |
|||
R1 = arg0[i & 7] |
|||
R2 = (R2 ^ R1) |
|||
# print(R2) |
|||
ss[i] = R2 |
|||
m = hashlib.md5() |
|||
m.update(base64.b64encode(bytes(i % 256 for i in ss))) |
|||
return str(params.get("st")), m.hexdigest(), str(params.get("sv")) |
|||
# return "st=" + str(params.get("st")) + "&sign=" + m.hexdigest() + "&sv=" + str(params.get("sv")) |
|||
|
|||
|
|||
def generateSign(): |
|||
params = { |
|||
"st": 1648992407201, # 毫秒级时间戳 |
|||
"sv": "120", |
|||
"functionId": 'serverConfig', |
|||
"uuid": '947934e94e0cb9e4', |
|||
"client": "android", |
|||
"clientVersion": '10.4.6', |
|||
# "body": '{"to":"https://plogin.m.jd.com/jd-mlogin/static/html/appjmp_blank.html"}' |
|||
"body": '{}' |
|||
} |
|||
# return getSign(params) |
|||
print(getSign(params)) |
|||
# print("正确结果:st=1648992407201&sign=474c50af52257126ae65700b825bdf4c&sv=120") |
|||
|
|||
|
|||
if __name__ == '__main__': |
|||
generateSign() |
@ -0,0 +1,31 @@ |
|||
import logging |
|||
import logging.handlers |
|||
import os |
|||
|
|||
''' |
|||
os.getcwd()代表py执行目录 |
|||
日志模块 |
|||
''' |
|||
|
|||
# 创建log文件夹 |
|||
new_path = os.path.join(os.getcwd(), 'log') |
|||
if not os.path.exists(new_path): |
|||
os.makedirs(new_path) |
|||
|
|||
LOG_FILENAME = 'log/jd.log' |
|||
logger = logging.getLogger() |
|||
|
|||
def set_logger(): |
|||
if not logger.handlers: |
|||
logger.setLevel(logging.INFO) |
|||
formatter = logging.Formatter('%(asctime)s - %(levelname)s: %(message)s') |
|||
console_handler = logging.StreamHandler() |
|||
console_handler.setFormatter(formatter) |
|||
logger.addHandler(console_handler) |
|||
file_handler = logging.handlers.RotatingFileHandler( |
|||
LOG_FILENAME, maxBytes=5*1024*1024, backupCount=5, encoding="utf-8") |
|||
file_handler.setFormatter(formatter) |
|||
logger.addHandler(file_handler) |
|||
|
|||
|
|||
set_logger() |
@ -0,0 +1,163 @@ |
|||
import hashlib |
|||
import platform |
|||
import random |
|||
import socket |
|||
from datetime import datetime |
|||
import sys |
|||
import os |
|||
|
|||
from http.cookies import SimpleCookie |
|||
|
|||
import json |
|||
import re |
|||
|
|||
from tools.ModifiedBase64 import ModifiedBase64 |
|||
|
|||
|
|||
def text_to_json(text, regex): |
|||
pattern = re.compile(regex) |
|||
text_list = re.findall(pattern, text) |
|||
_json = json.loads(text_list[0]) |
|||
return _json |
|||
|
|||
|
|||
def remove_unused_symbol(text): |
|||
return text.replace('\n', '').replace('\r', '').replace('\t', '') |
|||
|
|||
|
|||
def remove_redundant_comma(text): |
|||
""" |
|||
移除json多余逗号,避免json.loads报错 |
|||
""" |
|||
rex = r"""(?<=[}\]"'])\s*,\s*(?!\s*[{["'])""" |
|||
return re.sub(rex, "", text, 0) |
|||
|
|||
|
|||
def resource_path(relative_path): |
|||
if getattr(sys, 'frozen', False): |
|||
base_path = sys._MEIPASS |
|||
else: |
|||
base_path = os.path.abspath("../..") |
|||
return os.path.join(base_path, relative_path) |
|||
|
|||
|
|||
def export_file_name(): |
|||
return "ck-export-" + datetime.now().strftime('%Y%m%d%H%M%S') + ".txt" |
|||
|
|||
|
|||
def desktop_path(): |
|||
if platform.system() == 'Windows': |
|||
return r"C:\Users\Administrator\Desktop" |
|||
else: |
|||
return "/Users/xiaoqingsong/Desktop" |
|||
|
|||
|
|||
def is_json(text): |
|||
if text is None: |
|||
return False |
|||
try: |
|||
json.loads(text) |
|||
except ValueError: |
|||
return False |
|||
return True |
|||
|
|||
|
|||
def getTimeStamp(time): |
|||
""" |
|||
:param time: 形如 2021-01-20 10:10:20.120 |
|||
:return: |
|||
""" |
|||
ts = datetime.timestamp(datetime.strptime(time, '%Y-%m-%d %H:%M:%S.%f')) |
|||
return int(ts * 1000) |
|||
|
|||
|
|||
def getTimeStamp(time, format): |
|||
""" |
|||
:param format: %Y-%m-%d %H:%M:%S |
|||
:param time: 形如 2021-01-20 10:10:20 |
|||
:return: |
|||
""" |
|||
ts = datetime.timestamp(datetime.strptime(time, format)) |
|||
return int(ts * 1000) |
|||
|
|||
|
|||
def getNowTime(): |
|||
return datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-7] |
|||
|
|||
|
|||
def getCookieFromStr(rawStr): |
|||
cookie = SimpleCookie() |
|||
cookie.load(rawStr) |
|||
# Even though SimpleCookie is dictionary-like, it internally uses a Morsel object |
|||
# which is incompatible with requests. Manually construct a dictionary instead. |
|||
cookies = {} |
|||
for key, morsel in cookie.items(): |
|||
cookies[key] = morsel.value |
|||
return cookies |
|||
|
|||
|
|||
def get_random_number_str(length): |
|||
""" |
|||
生成随机数字字符串 |
|||
:param length: 字符串长度 |
|||
:return: |
|||
""" |
|||
num_str = ''.join(str(random.choice(range(10))) for _ in range(length)) |
|||
return num_str |
|||
|
|||
|
|||
def randomUUID(): |
|||
random_number = get_random_number_str(15) |
|||
random_str = hashlib.md5(random_number.encode('utf-8')).hexdigest()[:12] |
|||
return random_number + "-" + random_str |
|||
|
|||
|
|||
def get_host_ip(): |
|||
try: |
|||
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) |
|||
s.connect(('8.8.8.8', 80)) |
|||
ip = s.getsockname()[0] |
|||
finally: |
|||
s.close() |
|||
|
|||
return ip |
|||
|
|||
|
|||
def mb_encrypt(str): |
|||
v = ModifiedBase64() |
|||
return v.m23207r(str) |
|||
|
|||
|
|||
def get_ep(ts, uuid): |
|||
area = '13_1000_40488_54435' |
|||
d_model = 'PDNM00' |
|||
wifiBssid = 'unknown' |
|||
osVersion = '11' |
|||
d_brand = 'OPPO' |
|||
screen = '2161*1080' |
|||
uuid = uuid |
|||
aid = uuid |
|||
openudid = uuid |
|||
hdid = '' |
|||
|
|||
ep = { |
|||
'hdid': mb_encrypt(hdid), |
|||
'ts': ts, |
|||
'ridx': -1, |
|||
'cipher': { |
|||
'area': mb_encrypt(area), |
|||
'd_model': mb_encrypt(d_model), |
|||
'wifiBssid': mb_encrypt(wifiBssid), |
|||
'osVersion': mb_encrypt(osVersion), |
|||
'd_brand': mb_encrypt(d_brand), |
|||
'screen': mb_encrypt(screen), |
|||
'uuid': mb_encrypt(uuid), |
|||
'aid': mb_encrypt(aid), |
|||
'openudid': mb_encrypt(openudid), |
|||
}, |
|||
'ciphertype': 5, |
|||
'version': '1.2.0', |
|||
'appname': 'com.jingdong.app.mall', |
|||
} |
|||
|
|||
return ep |
Loading…
Reference in new issue