414 lines
14 KiB
Python
414 lines
14 KiB
Python
|
# 京乐玩-瓜分京豆 通用模板 create by doubi
|
|||
|
# openid 留空即可,不建议青龙使用,青龙玩不动,最好本地,本地在同目录下创建一个‘cklist.txt,将ck放在里面’
|
|||
|
# 目前新号助力10豆/人 老号助力2豆/人
|
|||
|
from secrets import choice
|
|||
|
import sys
|
|||
|
import re
|
|||
|
import random, asyncio, datetime, json, time, random, hashlib, os
|
|||
|
from unittest import result
|
|||
|
|
|||
|
import httpx
|
|||
|
from urllib.parse import quote_plus, unquote_plus
|
|||
|
from functools import partial
|
|||
|
import logging
|
|||
|
from requests import ConnectTimeout
|
|||
|
|
|||
|
activatyname = "京乐玩-瓜分京豆"
|
|||
|
salt = "cXRofWK6"
|
|||
|
me = "" # 小程序openid 留空
|
|||
|
group_size = 200 # 并发数建议 50-1500
|
|||
|
|
|||
|
inveteck = '' # 车头子ck
|
|||
|
|
|||
|
logging.basicConfig(
|
|||
|
level=logging.INFO,
|
|||
|
format="%(asctime)s %(levelname)s %(lineno)d %(message)s",
|
|||
|
datefmt="%H:%M:%S",
|
|||
|
)
|
|||
|
logger = logging.getLogger(activatyname)
|
|||
|
|
|||
|
httpx_client = httpx.AsyncClient()
|
|||
|
|
|||
|
# 随机ua
|
|||
|
def randomuserAgent():
|
|||
|
# global uuid, addressid, iosVer, iosV, clientVersion, iPhone, area, ADID, lng, lat
|
|||
|
uuid = "".join(
|
|||
|
random.sample(
|
|||
|
[
|
|||
|
"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",
|
|||
|
"0",
|
|||
|
"1",
|
|||
|
"2",
|
|||
|
"3",
|
|||
|
"4",
|
|||
|
"5",
|
|||
|
"6",
|
|||
|
"7",
|
|||
|
"8",
|
|||
|
"9",
|
|||
|
"a",
|
|||
|
"b",
|
|||
|
"c",
|
|||
|
"z",
|
|||
|
],
|
|||
|
40,
|
|||
|
)
|
|||
|
)
|
|||
|
addressid = "".join(random.sample("1234567898647", 10))
|
|||
|
iosVer = "".join(
|
|||
|
random.sample(["15.1.1", "14.5.1", "14.4", "14.3", "14.2", "14.1", "14.0.1"], 1)
|
|||
|
)
|
|||
|
iosV = iosVer.replace(".", "_")
|
|||
|
clientVersion = "".join(random.sample(["10.3.0", "10.2.7", "10.2.4"], 1))
|
|||
|
iPhone = "".join(random.sample(["8", "9", "10", "11", "12", "13"], 1))
|
|||
|
area = (
|
|||
|
"".join(random.sample("0123456789", 2))
|
|||
|
+ "_"
|
|||
|
+ "".join(random.sample("0123456789", 4))
|
|||
|
+ "_"
|
|||
|
+ "".join(random.sample("0123456789", 5))
|
|||
|
+ "_"
|
|||
|
+ "".join(random.sample("0123456789", 4))
|
|||
|
)
|
|||
|
ADID = (
|
|||
|
"".join(random.sample("0987654321ABCDEF", 8))
|
|||
|
+ "-"
|
|||
|
+ "".join(random.sample("0987654321ABCDEF", 4))
|
|||
|
+ "-"
|
|||
|
+ "".join(random.sample("0987654321ABCDEF", 4))
|
|||
|
+ "-"
|
|||
|
+ "".join(random.sample("0987654321ABCDEF", 4))
|
|||
|
+ "-"
|
|||
|
+ "".join(random.sample("0987654321ABCDEF", 12))
|
|||
|
)
|
|||
|
lng = "119.31991256596" + str(random.randint(100, 999))
|
|||
|
lat = "26.1187118976" + str(random.randint(100, 999))
|
|||
|
UserAgent = ""
|
|||
|
if not UserAgent:
|
|||
|
return f"jdapp;iPhone;10.0.4;{iosVer};{uuid};network/wifi;ADID/{ADID};model/iPhone{iPhone},1;addressid/{addressid};appBuild/167707;jdSupportDarkMode/0;Mozilla/5.0 (iPhone; CPU iPhone OS {iosV} like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/null;supportJDSHWK/1"
|
|||
|
else:
|
|||
|
return UserAgent
|
|||
|
|
|||
|
|
|||
|
# 检测ck状态
|
|||
|
async def check(ua, ck):
|
|||
|
try:
|
|||
|
url = "https://me-api.jd.com/user_new/info/GetJDUserInfoUnion"
|
|||
|
header = {
|
|||
|
"Host": "me-api.jd.com",
|
|||
|
"Accept": "*/*",
|
|||
|
"Connection": "keep-alive",
|
|||
|
"Cookie": ck,
|
|||
|
"User-Agent": ua,
|
|||
|
"Accept-Language": "zh-cn",
|
|||
|
"Referer": "https://home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&",
|
|||
|
"Accept-Encoding": "gzip, deflate",
|
|||
|
}
|
|||
|
result = (await httpx_client.get(url=url, headers=header)).text
|
|||
|
codestate = json.loads(result)
|
|||
|
if codestate["retcode"] == "1001":
|
|||
|
msg = "当前ck已失效,请检查"
|
|||
|
return {"code": 1001, "data": msg}
|
|||
|
elif codestate["retcode"] == "0" and "userInfo" in codestate["data"]:
|
|||
|
nickName = codestate["data"]["userInfo"]["baseInfo"]["nickname"]
|
|||
|
return {"code": 200, "name": nickName, "ck": ck}
|
|||
|
except Exception as e:
|
|||
|
return {"code": 0, "data": e}
|
|||
|
|
|||
|
|
|||
|
# 格式化时间
|
|||
|
def get_time():
|
|||
|
return datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|||
|
|
|||
|
|
|||
|
# 时间戳
|
|||
|
def get_now():
|
|||
|
return round(time.time() * 1000)
|
|||
|
|
|||
|
|
|||
|
# 获取京乐玩直播信息
|
|||
|
async def index(ck, ua):
|
|||
|
while 1:
|
|||
|
try:
|
|||
|
url = "https://jnk.m.jd.com/mission/user/index"
|
|||
|
headers = {
|
|||
|
"Accept-Encoding": "gzip,compress,br,deflate",
|
|||
|
"Connection": "keep-alive",
|
|||
|
"Host": "jnk.m.jd.com",
|
|||
|
"Cookie": ck,
|
|||
|
"Referer": "https://servicewechat.com/wx5afd69b196301a2f/135/page-frame.html",
|
|||
|
"User-Agent": ua,
|
|||
|
"content-type": "application/json",
|
|||
|
}
|
|||
|
body = {}
|
|||
|
res = (await httpx_client.post(url=url, headers=headers, data=json.dumps(body))).text
|
|||
|
res_json = json.loads(res)
|
|||
|
if res_json["success"]:
|
|||
|
data = res_json["data"]
|
|||
|
for key in data:
|
|||
|
if "live" in key.keys():
|
|||
|
return {"success": True, "data": key["live"]}
|
|||
|
else:
|
|||
|
return {"success": False}
|
|||
|
except:
|
|||
|
pass
|
|||
|
|
|||
|
|
|||
|
def get_viewId(pin, actId):
|
|||
|
tt = str(get_now()) # (new Date).getTime() 第一个tt生成viewid,然后viewid不变
|
|||
|
bePromotion = "1"
|
|||
|
pin = unquote_plus(pin)
|
|||
|
viewId = hashlib.md5(
|
|||
|
quote_plus(pin + actId + tt + salt + bePromotion).encode("utf-8")
|
|||
|
).hexdigest()
|
|||
|
token = gettoken(viewId, actId)
|
|||
|
msg = {
|
|||
|
"viewId": str(viewId),
|
|||
|
"tt": int(tt),
|
|||
|
"tokenVersion": 2,
|
|||
|
"token": str(token),
|
|||
|
"actId": int(actId),
|
|||
|
"bePromotion": 1,
|
|||
|
}
|
|||
|
logger.info(msg)
|
|||
|
return msg
|
|||
|
|
|||
|
|
|||
|
def gettoken(viewId, actId):
|
|||
|
tt = str(get_now())
|
|||
|
token = hashlib.md5(
|
|||
|
quote_plus(viewId + actId + tt + salt).encode("utf-8")
|
|||
|
).hexdigest()
|
|||
|
return token
|
|||
|
|
|||
|
|
|||
|
def get_token(viewId, actId):
|
|||
|
tt = str(get_now())
|
|||
|
token = hashlib.md5(
|
|||
|
quote_plus(viewId + actId + tt + salt).encode("utf-8")
|
|||
|
).hexdigest()
|
|||
|
msg = {
|
|||
|
"viewId": str(viewId),
|
|||
|
"tt": int(tt),
|
|||
|
"tokenVersion": 2,
|
|||
|
"token": str(token),
|
|||
|
"actId": int(actId),
|
|||
|
"bePromotion": 1,
|
|||
|
}
|
|||
|
return msg
|
|||
|
|
|||
|
|
|||
|
# promotion/invite
|
|||
|
async def post_url(def_id, ck, body):
|
|||
|
while 1:
|
|||
|
try:
|
|||
|
url = "https://jnk.m.jd.com/" + def_id
|
|||
|
headers = {
|
|||
|
"Cookie": f"{ck}wxclient=gxhwx;ie_ai=1;",
|
|||
|
"content-type": "application/json",
|
|||
|
"Connection": "keep-alive",
|
|||
|
"Accept-Encoding": "gzip,compress,br,deflate",
|
|||
|
"Referer": "https://servicewechat.com/wx5afd69b196301a2f/135/page-frame.html",
|
|||
|
"Host": "jnk.m.jd.com",
|
|||
|
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.18(0x1800123f) NetType/WIFI Language/zh_CN",
|
|||
|
}
|
|||
|
bdoy = json.dumps(body)
|
|||
|
res = (await httpx_client.post(url=url, headers=headers, data=json.dumps(body))).text
|
|||
|
pin = re.findall(r"(pt_pin=([^; ]+)(?=;?))", ck)[0][1]
|
|||
|
logger.info(f'post_url:{unquote_plus(pin)}:{res}')
|
|||
|
res_json = json.loads(res)
|
|||
|
# return json.dumps(res_json,indent=2,ensure_ascii=False)
|
|||
|
return res_json
|
|||
|
except:
|
|||
|
pass
|
|||
|
|
|||
|
# 检查pin
|
|||
|
def checkpin(cks: list, pin):
|
|||
|
for ck in cks:
|
|||
|
if pin in ck:
|
|||
|
return ck
|
|||
|
else:
|
|||
|
None
|
|||
|
|
|||
|
async def task(ck, promotionId):
|
|||
|
pin = re.findall(r"(pt_pin=([^; ]+)(?=;?))", ck)[0][1]
|
|||
|
logger.info(f"您好[{pin}]")
|
|||
|
result = await post_url(
|
|||
|
"mission/user/promotion/status", ck, {"promotionId": promotionId}
|
|||
|
)
|
|||
|
res = get_viewId(pin, str(promotionId))
|
|||
|
viewId = res["viewId"]
|
|||
|
result = await post_url("viewlog/user/recordLog", ck, res)
|
|||
|
await asyncio.sleep(25)
|
|||
|
success = 0
|
|||
|
while True:
|
|||
|
token = get_token(viewId, str(promotionId))
|
|||
|
result = await post_url("viewlog/user/recordLog", ck, token)
|
|||
|
if result['code']==-100 or '未登录' in str(result):
|
|||
|
return
|
|||
|
if result["code"] == 0 and success == 5:
|
|||
|
logger.info(result["msg"])
|
|||
|
break
|
|||
|
if success == 2 or success == 3:
|
|||
|
result = await post_url(
|
|||
|
"mission/user/promotion/join",
|
|||
|
ck,
|
|||
|
{
|
|||
|
"promotionId": promotionId,
|
|||
|
"nickName": "微信用户",
|
|||
|
"avatarUrl": "https://static-alias-1.360buyimg.com/jzt/mp/images/default_user_img.png",
|
|||
|
"openId": "",
|
|||
|
},
|
|||
|
)
|
|||
|
if result['code']==1:
|
|||
|
break
|
|||
|
else:
|
|||
|
success += 1
|
|||
|
continue
|
|||
|
else:
|
|||
|
success += 1
|
|||
|
continue
|
|||
|
await post_url("mission/user/promotion/status", ck, {"promotionId": promotionId})
|
|||
|
await post_url(
|
|||
|
"mission/user/promotion/join",
|
|||
|
ck,
|
|||
|
{
|
|||
|
"promotionId": promotionId,
|
|||
|
"nickName": "微信用户",
|
|||
|
"avatarUrl": "https://static-alias-1.360buyimg.com/jzt/mp/images/default_user_img.png",
|
|||
|
"openId": "",
|
|||
|
},
|
|||
|
)
|
|||
|
|
|||
|
async def promotionCreate(ck):
|
|||
|
number = '123456789'
|
|||
|
sa = []
|
|||
|
for i in range(6):
|
|||
|
sa.append(choice(number))
|
|||
|
numbers = ''.join(sa)
|
|||
|
body = {"nickName":"微信用户",
|
|||
|
"avatarUrl":"https://static-alias-1.360buyimg.com/jzt/mp/images/default_user_img.png",
|
|||
|
"openId":"",
|
|||
|
"cellphone":f"15214{str(numbers)}"
|
|||
|
}
|
|||
|
result = await post_url('mission/user/promotion/create',ck,body)
|
|||
|
return result
|
|||
|
|
|||
|
async def search(ck,ua):
|
|||
|
while 1:
|
|||
|
try:
|
|||
|
result = await index(ck, ua) # 获取频道信息
|
|||
|
if not result["success"]:
|
|||
|
logger.warn("目前没有任何直播间信息")
|
|||
|
return [],None
|
|||
|
liveres = []
|
|||
|
for n, live in enumerate(result["data"], 1):
|
|||
|
liveId = live["liveId"] # 直播id
|
|||
|
result = await post_url('mission/user/promotion/invite',ck,{
|
|||
|
"nickName":"微信用户",
|
|||
|
"avatarUrl":"https://static-alias-1.360buyimg.com/jzt/mp/images/default_user_img.png",
|
|||
|
"openId":str(''),"liveId":liveId})
|
|||
|
if result['success']:
|
|||
|
if result['msg'] is None:
|
|||
|
liveId = result['data']['liveId']
|
|||
|
liveres.append(str(liveId))
|
|||
|
if '未注册' in str(result):
|
|||
|
result = await promotionCreate(ck)
|
|||
|
if result['success']:
|
|||
|
print('注册成功')
|
|||
|
else:
|
|||
|
print('注册失败log:'+str(result))
|
|||
|
else:
|
|||
|
print(result['msg'])
|
|||
|
continue
|
|||
|
|
|||
|
return liveres
|
|||
|
except:
|
|||
|
pass
|
|||
|
|
|||
|
# 主程序
|
|||
|
async def main():
|
|||
|
try:
|
|||
|
cks = os.environ["JD_COOKIE"].split("&")
|
|||
|
except:
|
|||
|
with open('cklist.txt','r') as f:
|
|||
|
cks = f.read().split('\n')
|
|||
|
logger.info(f"共:{len(cks)}个CK")
|
|||
|
|
|||
|
while True:
|
|||
|
logger.info("------轮询------")
|
|||
|
logger.info(f"轮询ck")
|
|||
|
rand_ck = choice(cks[5:15])
|
|||
|
ua = randomuserAgent() # 随机ua
|
|||
|
if inveteck == '':
|
|||
|
logger.info(f"没有配置车头子ck,快去填写吧")
|
|||
|
return
|
|||
|
liveres = await search(rand_ck, ua)
|
|||
|
if len(liveres) == 0:
|
|||
|
logger.info("暂无活动,等待")
|
|||
|
await asyncio.sleep(5) # 等待时间
|
|||
|
continue
|
|||
|
|
|||
|
liveId1 = liveres[0]
|
|||
|
while 1:
|
|||
|
result = await post_url(
|
|||
|
"mission/user/promotion/invite",
|
|||
|
inveteck,
|
|||
|
{
|
|||
|
"nickName": "微信用户",
|
|||
|
"avatarUrl": "https://static-alias-1.360buyimg.com/jzt/mp/images/default_user_img.png",
|
|||
|
"openId": str(me),
|
|||
|
"liveId": liveId1,
|
|||
|
},
|
|||
|
)
|
|||
|
logger.info(f'result:{result}')
|
|||
|
if '未注册' in str(result):
|
|||
|
result = await promotionCreate(inveteck)
|
|||
|
if result['success']:
|
|||
|
print('注册成功')
|
|||
|
break
|
|||
|
if '火爆' in str(result):
|
|||
|
continue
|
|||
|
if "promotionId" in result["data"]:
|
|||
|
promotionId = result["data"]["promotionId"]
|
|||
|
break
|
|||
|
else:
|
|||
|
logger.info(result["msg"])
|
|||
|
return
|
|||
|
|
|||
|
cks = cks[1:]
|
|||
|
for idx in range(0, len(cks), group_size):
|
|||
|
logger.info(f"开始执行第{idx//group_size + 1}组")
|
|||
|
group = cks[idx : idx + group_size]
|
|||
|
done, pending = await asyncio.wait(
|
|||
|
[asyncio.create_task(task(ck, promotionId)) for ck in group], timeout=None
|
|||
|
)
|
|||
|
|
|||
|
if __name__ == "__main__":
|
|||
|
asyncio.run(main())
|