mirror of https://github.com/6dylan6/jdpro.git
This commit is contained in:
parent
10c7b35b6b
commit
a52c77b16e
234
jd_wskey.py
234
jd_wskey.py
|
@ -1,20 +1,20 @@
|
||||||
# -*- coding: utf-8 -*
|
# -*- coding: utf-8 -*
|
||||||
'''
|
'''
|
||||||
定时自定义
|
|
||||||
2 10 20 5 * jd_wskey.py
|
|
||||||
new Env('wskey转换');
|
new Env('wskey转换');
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import socket
|
|
||||||
import base64
|
import base64
|
||||||
import json
|
import hashlib
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import logging
|
|
||||||
import time
|
|
||||||
import re
|
|
||||||
import hmac
|
import hmac
|
||||||
|
import json
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import random
|
||||||
|
import re
|
||||||
|
import socket
|
||||||
import struct
|
import struct
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import uuid
|
||||||
|
|
||||||
WSKEY_MODE = 0
|
WSKEY_MODE = 0
|
||||||
# 0 = Default / 1 = Debug!
|
# 0 = Default / 1 = Debug!
|
||||||
|
@ -40,7 +40,7 @@ except Exception as err:
|
||||||
logger.debug(str(err)) # 调试日志输出
|
logger.debug(str(err)) # 调试日志输出
|
||||||
logger.info("无推送文件") # 标准日志输出
|
logger.info("无推送文件") # 标准日志输出
|
||||||
|
|
||||||
ver = 31207 # 版本号
|
ver = 40904 # 版本号
|
||||||
|
|
||||||
|
|
||||||
def ttotp(key):
|
def ttotp(key):
|
||||||
|
@ -52,6 +52,97 @@ def ttotp(key):
|
||||||
return str(binary)[-6:].zfill(6)
|
return str(binary)[-6:].zfill(6)
|
||||||
|
|
||||||
|
|
||||||
|
def sign_core(par):
|
||||||
|
arr = [0x37, 0x92, 0x44, 0x68, 0xA5, 0x3D, 0xCC, 0x7F, 0xBB, 0xF, 0xD9, 0x88, 0xEE, 0x9A, 0xE9, 0x5A]
|
||||||
|
key2 = b"80306f4370b39fd5630ad0529f77adb6"
|
||||||
|
arr1 = [0 for _ in range(len(par))]
|
||||||
|
for i in range(len(par)):
|
||||||
|
r0 = int(par[i])
|
||||||
|
r2 = arr[i & 0xf]
|
||||||
|
r4 = int(key2[i & 7])
|
||||||
|
r0 = r2 ^ r0
|
||||||
|
r0 = r0 ^ r4
|
||||||
|
r0 = r0 + r2
|
||||||
|
r2 = r2 ^ r0
|
||||||
|
r1 = int(key2[i & 7])
|
||||||
|
r2 = r2 ^ r1
|
||||||
|
arr1[i] = r2 & 0xff
|
||||||
|
return bytes(arr1)
|
||||||
|
|
||||||
|
def get_sign(functionId, body, uuid, client, clientVersion, st, sv):
|
||||||
|
all_arg = "functionId=%s&body=%s&uuid=%s&client=%s&clientVersion=%s&st=%s&sv=%s" % (
|
||||||
|
functionId, body, uuid, client, clientVersion, st, sv)
|
||||||
|
ret_bytes = sign_core(str.encode(all_arg))
|
||||||
|
info = hashlib.md5(base64.b64encode(ret_bytes)).hexdigest()
|
||||||
|
return info
|
||||||
|
|
||||||
|
def base64Encode(string):
|
||||||
|
string1 = "KLMNOPQRSTABCDEFGHIJUVWXYZabcdopqrstuvwxefghijklmnyz0123456789+/"
|
||||||
|
string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
|
||||||
|
return base64.b64encode(string.encode("utf-8")).decode('utf-8').translate(str.maketrans(string1, string2))
|
||||||
|
|
||||||
|
def base64Decode(string):
|
||||||
|
string1 = "KLMNOPQRSTABCDEFGHIJUVWXYZabcdopqrstuvwxefghijklmnyz0123456789+/"
|
||||||
|
string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
|
||||||
|
stringbase = base64.b64decode(string.translate(str.maketrans(string1, string2))).decode('utf-8')
|
||||||
|
return stringbase
|
||||||
|
|
||||||
|
def genJDUA():
|
||||||
|
st = round(time.time() * 1000)
|
||||||
|
aid = base64Encode(''.join(str(uuid.uuid4()).split('-'))[16:])
|
||||||
|
oaid = base64Encode(''.join(str(uuid.uuid4()).split('-'))[16:])
|
||||||
|
ua = 'jdapp;android;11.1.4;;;appBuild/98176;ef/1;ep/{"hdid":"JM9F1ywUPwflvMIpYPok0tt5k9kW4ArJEU3lfLhxBqw=","ts":%s,"ridx":-1,"cipher":{"sv":"CJS=","ad":"%s","od":"%s","ov":"CzO=","ud":"%s"},"ciphertype":5,"version":"1.2.0","appname":"com.jingdong.app.mall"};Mozilla/5.0 (Linux; Android 12; M2102K1C Build/SKQ1.220303.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/97.0.4692.98 Mobile Safari/537.36' % (st, aid, oaid, aid)
|
||||||
|
return ua
|
||||||
|
|
||||||
|
def genParams():
|
||||||
|
suid = ''.join(str(uuid.uuid4()).split('-'))[16:]
|
||||||
|
buid = base64Encode(suid)
|
||||||
|
st = round(time.time() * 1000)
|
||||||
|
sv = random.choice(["102", "111", "120"])
|
||||||
|
ep = json.dumps({
|
||||||
|
"hdid": "JM9F1ywUPwflvMIpYPok0tt5k9kW4ArJEU3lfLhxBqw=",
|
||||||
|
"ts": st,
|
||||||
|
"ridx": -1,
|
||||||
|
"cipher": {
|
||||||
|
"area": "CV8yEJUzXzU0CNG0XzK=",
|
||||||
|
"d_model": "JWunCVVidRTr",
|
||||||
|
"wifiBssid": "dW5hbw93bq==",
|
||||||
|
"osVersion": "CJS=",
|
||||||
|
"d_brand": "WQvrb21f",
|
||||||
|
"screen": "CJuyCMenCNq=",
|
||||||
|
"uuid": buid,
|
||||||
|
"aid": buid,
|
||||||
|
"openudid": buid
|
||||||
|
},
|
||||||
|
"ciphertype": 5,
|
||||||
|
"version": "1.2.0",
|
||||||
|
"appname": "com.jingdong.app.mall"
|
||||||
|
}).replace(" ", "")
|
||||||
|
body = '{"to":"https%3a%2f%2fplogin.m.jd.com%2fjd-mlogin%2fstatic%2fhtml%2fappjmp_blank.html"}'
|
||||||
|
sign = get_sign("genToken", body, suid, "android", "11.1.4", st, sv)
|
||||||
|
params = {
|
||||||
|
'functionId': 'genToken',
|
||||||
|
'clientVersion': '11.1.4',
|
||||||
|
'build': '98176',
|
||||||
|
'client': 'android',
|
||||||
|
'partner': 'google',
|
||||||
|
'oaid': suid,
|
||||||
|
'sdkVersion': '31',
|
||||||
|
'lang': 'zh_CN',
|
||||||
|
'harmonyOs': '0',
|
||||||
|
'networkType': 'UNKNOWN',
|
||||||
|
'uemps': '0-2',
|
||||||
|
'ext': '{"prstate": "0", "pvcStu": "1"}',
|
||||||
|
'eid': 'eidAcef08121fds9MoeSDdMRQ1aUTyb1TyPr2zKHk5Asiauw+K/WvS1Ben1cH6N0UnBd7lNM50XEa2kfCcA2wwThkxZc1MuCNtfU/oAMGBqadgres4BU',
|
||||||
|
'ef': '1',
|
||||||
|
'ep': ep,
|
||||||
|
'st': st,
|
||||||
|
'sign': sign,
|
||||||
|
'sv': sv
|
||||||
|
}
|
||||||
|
return params
|
||||||
|
|
||||||
|
|
||||||
def ql_send(text):
|
def ql_send(text):
|
||||||
if "WSKEY_SEND" in os.environ and os.environ["WSKEY_SEND"] == 'disable':
|
if "WSKEY_SEND" in os.environ and os.environ["WSKEY_SEND"] == 'disable':
|
||||||
return True
|
return True
|
||||||
|
@ -237,7 +328,7 @@ def check_ck(ck) -> bool: # 方法 检查 Cookie有效性 使用变量传递
|
||||||
headers = {
|
headers = {
|
||||||
'Cookie': ck,
|
'Cookie': ck,
|
||||||
'Referer': 'https://home.m.jd.com/myJd/home.action',
|
'Referer': 'https://home.m.jd.com/myJd/home.action',
|
||||||
'user-agent': ua
|
'user-agent': genJDUA()
|
||||||
} # 设置 HTTP头
|
} # 设置 HTTP头
|
||||||
try:
|
try:
|
||||||
res = requests.get(url=url, headers=headers, verify=False, timeout=10,
|
res = requests.get(url=url, headers=headers, verify=False, timeout=10,
|
||||||
|
@ -267,21 +358,22 @@ def check_ck(ck) -> bool: # 方法 检查 Cookie有效性 使用变量传递
|
||||||
|
|
||||||
# 返回值 bool jd_ck
|
# 返回值 bool jd_ck
|
||||||
def getToken(wskey): # 方法 获取 Wskey转换使用的 Token 由 JD_API 返回 这里传递 wskey
|
def getToken(wskey): # 方法 获取 Wskey转换使用的 Token 由 JD_API 返回 这里传递 wskey
|
||||||
try:
|
# try:
|
||||||
url = str(base64.b64decode(url_t).decode()) + 'api/genToken' # 设置云端服务器地址 路由为 genToken
|
# url = str(base64.b64decode(url_t).decode()) + 'api/genToken' # 设置云端服务器地址 路由为 genToken
|
||||||
header = {"User-Agent": ua} # 设置 HTTP头
|
# header = {"User-Agent": ua} # 设置 HTTP头
|
||||||
params = requests.get(url=url, headers=header, verify=False, timeout=20).json() # 设置 HTTP请求参数 超时 20秒 Json解析
|
# params = requests.get(url=url, headers=header, verify=False, timeout=20).json() # 设置 HTTP请求参数 超时 20秒 Json解析
|
||||||
except Exception as err:
|
# except Exception as err:
|
||||||
logger.info("Params参数获取失败") # 标准日志输出
|
# logger.info("Params参数获取失败") # 标准日志输出
|
||||||
logger.debug(str(err)) # 调试日志输出
|
# logger.debug(str(err)) # 调试日志输出
|
||||||
# return False, wskey # 返回 -> False[Bool], Wskey
|
# # return False, wskey # 返回 -> False[Bool], Wskey
|
||||||
return False # 返回 -> False[Bool], Wskey
|
# return False # 返回 -> False[Bool], Wskey
|
||||||
|
params = genParams()
|
||||||
headers = {
|
headers = {
|
||||||
'cookie': wskey,
|
'cookie': wskey,
|
||||||
'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
|
'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
|
||||||
'charset': 'UTF-8',
|
'charset': 'UTF-8',
|
||||||
'accept-encoding': 'br,gzip,deflate',
|
'accept-encoding': 'br,gzip,deflate',
|
||||||
'user-agent': ua
|
'user-agent': genJDUA()
|
||||||
} # 设置 HTTP头
|
} # 设置 HTTP头
|
||||||
url = 'https://api.m.jd.com/client.action' # 设置 URL地址
|
url = 'https://api.m.jd.com/client.action' # 设置 URL地址
|
||||||
data = 'body=%7B%22to%22%3A%22https%253a%252f%252fplogin.m.jd.com%252fjd-mlogin%252fstatic%252fhtml%252fappjmp_blank.html%22%7D&' # 设置 POST 载荷
|
data = 'body=%7B%22to%22%3A%22https%253a%252f%252fplogin.m.jd.com%252fjd-mlogin%252fstatic%252fhtml%252fappjmp_blank.html%22%7D&' # 设置 POST 载荷
|
||||||
|
@ -307,7 +399,7 @@ def appjmp(wskey, tokenKey): # 方法 传递 wskey & tokenKey
|
||||||
# return False, wskey # 返回 -> False[Bool], Wskey
|
# return False, wskey # 返回 -> False[Bool], Wskey
|
||||||
return False # 返回 -> False[Bool], Wskey
|
return False # 返回 -> False[Bool], Wskey
|
||||||
headers = {
|
headers = {
|
||||||
'User-Agent': ua,
|
'User-Agent': genJDUA(),
|
||||||
'accept': 'accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
|
'accept': 'accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
|
||||||
'x-requested-with': 'com.jingdong.app.mall'
|
'x-requested-with': 'com.jingdong.app.mall'
|
||||||
} # 设置 HTTP头
|
} # 设置 HTTP头
|
||||||
|
@ -476,52 +568,52 @@ def ql_insert(i_ck): # 方法 插入新变量
|
||||||
logger.info("\n账号添加失败\n--------------------\n") # 标准日志输出
|
logger.info("\n账号添加失败\n--------------------\n") # 标准日志输出
|
||||||
|
|
||||||
|
|
||||||
def cloud_info(): # 方法 云端信息
|
# def cloud_info(): # 方法 云端信息
|
||||||
url = str(base64.b64decode(url_t).decode()) + 'api/check_api' # 设置 URL地址 路由 [check_api]
|
# url = str(base64.b64decode(url_t).decode()) + 'api/check_api' # 设置 URL地址 路由 [check_api]
|
||||||
for i in range(3): # For循环 3次
|
# for i in range(3): # For循环 3次
|
||||||
try:
|
# try:
|
||||||
headers = {"authorization": "Bearer Shizuku"} # 设置 HTTP头
|
# headers = {"authorization": "Bearer Shizuku"} # 设置 HTTP头
|
||||||
res = requests.get(url=url, verify=False, headers=headers, timeout=20).text # HTTP[GET] 请求 超时 20秒
|
# res = requests.get(url=url, verify=False, headers=headers, timeout=20).text # HTTP[GET] 请求 超时 20秒
|
||||||
except requests.exceptions.ConnectTimeout:
|
# except requests.exceptions.ConnectTimeout:
|
||||||
logger.info("\n获取云端参数超时, 正在重试!" + str(i)) # 标准日志输出
|
# logger.info("\n获取云端参数超时, 正在重试!" + str(i)) # 标准日志输出
|
||||||
time.sleep(1) # 休眠 1秒
|
# time.sleep(1) # 休眠 1秒
|
||||||
continue # 循环继续
|
# continue # 循环继续
|
||||||
except requests.exceptions.ReadTimeout:
|
# except requests.exceptions.ReadTimeout:
|
||||||
logger.info("\n获取云端参数超时, 正在重试!" + str(i)) # 标准日志输出
|
# logger.info("\n获取云端参数超时, 正在重试!" + str(i)) # 标准日志输出
|
||||||
time.sleep(1) # 休眠 1秒
|
# time.sleep(1) # 休眠 1秒
|
||||||
continue # 循环继续
|
# continue # 循环继续
|
||||||
except Exception as err:
|
# except Exception as err:
|
||||||
logger.info("\n未知错误云端, 退出脚本!") # 标准日志输出
|
# logger.info("\n未知错误云端, 退出脚本!") # 标准日志输出
|
||||||
logger.debug(str(err)) # 调试日志输出
|
# logger.debug(str(err)) # 调试日志输出
|
||||||
sys.exit(1) # 脚本退出
|
# sys.exit(1) # 脚本退出
|
||||||
else:
|
# else:
|
||||||
try:
|
# try:
|
||||||
c_info = json.loads(res) # json读取参数
|
# c_info = json.loads(res) # json读取参数
|
||||||
except Exception as err:
|
# except Exception as err:
|
||||||
logger.info("云端参数解析失败") # 标准日志输出
|
# logger.info("云端参数解析失败") # 标准日志输出
|
||||||
logger.debug(str(err)) # 调试日志输出
|
# logger.debug(str(err)) # 调试日志输出
|
||||||
sys.exit(1) # 脚本退出
|
# sys.exit(1) # 脚本退出
|
||||||
else:
|
# else:
|
||||||
return c_info # 返回 -> c_info
|
# return c_info # 返回 -> c_info
|
||||||
|
|
||||||
|
|
||||||
def check_cloud():
|
# def check_cloud():
|
||||||
url_list = ['aHR0cHM6Ly9hcGkubW9tb2UubGluay8=', 'aHR0cHM6Ly9hcGkubGltb2UuZXUub3JnLw==',
|
# url_list = ['aHR0cHM6Ly9hcGkubW9tb2UubGluay8=', 'aHR0cHM6Ly9hcGkubGltb2UuZXUub3JnLw==',
|
||||||
'aHR0cHM6Ly9hcGkuaWxpeWEuY2Yv']
|
# 'aHR0cHM6Ly9hcGkuaWxpeWEuY2Yv']
|
||||||
for i in url_list:
|
# for i in url_list:
|
||||||
url = str(base64.b64decode(i).decode()) # 设置 url地址 [str]
|
# url = str(base64.b64decode(i).decode()) # 设置 url地址 [str]
|
||||||
try:
|
# try:
|
||||||
requests.get(url=url, verify=False, timeout=10) # HTTP[GET]请求 超时 10秒
|
# requests.get(url=url, verify=False, timeout=10) # HTTP[GET]请求 超时 10秒
|
||||||
except Exception as err:
|
# except Exception as err:
|
||||||
logger.debug(str(err)) # 调试日志输出
|
# logger.debug(str(err)) # 调试日志输出
|
||||||
continue # 循环继续
|
# continue # 循环继续
|
||||||
else: # 分支判断
|
# else: # 分支判断
|
||||||
info = ['HTTPS', 'Eu_HTTPS', 'CloudFlare'] # 输出信息[List]
|
# info = ['HTTPS', 'Eu_HTTPS', 'CloudFlare'] # 输出信息[List]
|
||||||
logger.info(str(info[url_list.index(i)]) + " Server Check OK\n--------------------\n") # 标准日志输出
|
# logger.info(str(info[url_list.index(i)]) + " Server Check OK\n--------------------\n") # 标准日志输出
|
||||||
return i # 返回 ->i
|
# return i # 返回 ->i
|
||||||
logger.info("\n云端地址全部失效, 请检查网络!") # 标准日志输出
|
# logger.info("\n云端地址全部失效, 请检查网络!") # 标准日志输出
|
||||||
ql_send('云端地址失效. 请联系作者或者检查网络.') # 推送消息
|
# ql_send('云端地址失效. 请联系作者或者检查网络.') # 推送消息
|
||||||
sys.exit(1) # 脚本退出
|
# sys.exit(1) # 脚本退出
|
||||||
|
|
||||||
|
|
||||||
def check_port(): # 方法 检查变量传递端口
|
def check_port(): # 方法 检查变量传递端口
|
||||||
|
@ -543,10 +635,10 @@ if __name__ == '__main__': # Python主函数执行入口
|
||||||
ql_session = requests.session()
|
ql_session = requests.session()
|
||||||
token = ql_login() # 调用方法 [ql_login] 并赋值 [token]
|
token = ql_login() # 调用方法 [ql_login] 并赋值 [token]
|
||||||
ql_id = check_id()
|
ql_id = check_id()
|
||||||
url_t = check_cloud()
|
# url_t = check_cloud()
|
||||||
cloud_arg = cloud_info()
|
# cloud_arg = cloud_info()
|
||||||
update()
|
# update()
|
||||||
ua = cloud_arg['User-Agent']
|
# ua = cloud_arg['User-Agent']
|
||||||
wslist = get_wskey()
|
wslist = get_wskey()
|
||||||
envlist = get_env()
|
envlist = get_env()
|
||||||
sleepTime = int(os.environ.get("WSKEY_SLEEP", "10") if str(os.environ.get("WSKEY_SLEEP")).isdigit() else "10")
|
sleepTime = int(os.environ.get("WSKEY_SLEEP", "10") if str(os.environ.get("WSKEY_SLEEP")).isdigit() else "10")
|
||||||
|
|
Loading…
Reference in New Issue