1.购买服务器阿里云:服务器购买地址https://t.aliyun.com/U/Bg6shY若失效,可用地址
阿里云:
服务器购买地址
https://t.aliyun.com/U/Bg6shY若失效,可用地址
https://www.aliyun.com/daily-act/ecs/activity_selection?source=5176.29345612&userCode=49hts92d腾讯云:
https://curl.qcloud.com/wJpWmSfU若失效,可用地址
https://cloud.tencent.com/act/cps/redirect?redirect=2446&cps_key=ad201ee2ef3b771157f72ee5464b1fea&from=console华为云
https://activity.huaweicloud.com/cps.html?fromacct=64b5cf7cc11b4840bb4ed2ea0b2f4468&utm_source=V1g3MDY4NTY=&utm_medium=cps&utm_campaign=2019052.部署教程
3.代码如下
# -*- coding: UTF-8 -*-import requestsimport jsonimport timeimport randomimport osfrom requests.exceptions import RequestExceptionfrom collections import defaultdictTOKEN_LIST = os.getenv('TOKEN_LIST', '')SEND_KEY_LIST = os.getenv('SEND_KEY_LIST', '')# 接口配置url = 'https://m.jlc.com/api/activity/sign/signIn?source=3'gold_bean_url = "https://m.jlc.com/api/appPlatform/center/assets/selectPersonalAssetsInfo"seventh_day_url = "https://m.jlc.com/api/activity/sign/receiveVoucher"# ======== 工具函数 ========def mask_account(account):"""用于打印时隐藏部分账号信息"""if len(account) >= 4:return account[:2] + '****' + account[-2:]return '****'def mask_json_customer_code(data):"""递归地脱敏 JSON 中的 customerCode 字段"""if isinstance(data, dict):new_data = {}for k, v in data.items():if k == "customerCode" and isinstance(v, str):new_data[k] = v[:1] + "xxxxx" + v[-2:] # 例: 1xxxxx8Aelse:new_data[k] = mask_json_customer_code(v)return new_dataelif isinstance(data, list):return [mask_json_customer_code(i) for i in data]else:return data# ======== 推送通知 ========def send_msg_by_server(send_key, title, content):push_url = f'https://api.ftqq.com/{send_key}.send'data = {'text': title,'desp': content}try:response = requests.post(push_url, data=data)return response.json()except RequestException:return None# ======== 单个账号签到逻辑 ========def sign_in(access_token):headers = {'X-JLC-AccessToken': access_token,'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_2_1 like Mac OS X) ''AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 Html5Plus/1.0 (Immersed/20) JlcMobileApp',}try:# 1. 获取金豆信息(先获取,用于获取 customer_code)bean_response = requests.get(gold_bean_url, headers=headers)bean_response.raise_for_status()bean_result = bean_response.json()# 获取 customerCodecustomer_code = bean_result['data']['customerCode']integral_voucher = bean_result['data']['integralVoucher']# 2. 执行签到请求sign_response = requests.get(url, headers=headers)sign_response.raise_for_status()sign_result = sign_response.json()# 打印签到响应 JSON(已脱敏)# print(f" [账号{mask_account(customer_code)}] 签到响应JSON:")# print(json.dumps(mask_json_customer_code(sign_result), indent=2, ensure_ascii=False))# 检查签到是否成功if not sign_result.get('success'):message = sign_result.get('message', '未知错误')if '已经签到' in message:print(f" [账号{mask_account(customer_code)}] 今日已签到")return None # 今日已签到,不返回消息else:print(f" [账号{mask_account(customer_code)}] 签到失败 - {message}")return None # 签到失败,不返回消息# 解析签到数据data = sign_result.get('data', {})# 安全地获取 gainNum 和 statusgain_num = data.get('gainNum') if data else Nonestatus = data.get('status') if data else None# 处理签到结果if status and status > 0:if gain_num is not None and gain_num != 0:print(f" [账号{mask_account(customer_code)}] 今日签到成功")return f" 账号({mask_account(customer_code)}):获取{gain_num}个金豆,当前总数:{integral_voucher + gain_num}"else:# 第七天特殊处理seventh_response = requests.get(seventh_day_url, headers=headers)seventh_response.raise_for_status()seventh_result = seventh_response.json()if seventh_result.get("success"):print(f" [账号{mask_account(customer_code)}] 第七天签到成功")return f" 账号({mask_account(customer_code)}):第七天签到成功,当前金豆总数:{integral_voucher + 8}"else:print(f" [账号{mask_account(customer_code)}] 第七天签到失败,无金豆获取")return Noneelse:print(f" [账号{mask_account(customer_code)}] 今日已签到或签到失败")return Noneexcept RequestException as e:print(f" [账号{mask_account(access_token)}] 网络请求失败: {str(e)}")return Noneexcept KeyError as e:print(f" [账号{mask_account(access_token)}] 数据解析失败: 缺少键 {str(e)}")return Noneexcept Exception as e:print(f" [账号{mask_account(access_token)}] 未知错误: {str(e)}")return None# ======== 主函数 ========def main():AccessTokenList = [token.strip() for token in TOKEN_LIST.split(',') if token.strip()]SendKeyList = [key.strip() for key in SEND_KEY_LIST.split(',') if key.strip()]# 检查配置是否为空if not AccessTokenList:print(" 请设置 TOKENS")returnif not SendKeyList:print(" 请设置 SENDKEYS")return# 确保长度一致min_length = min(len(AccessTokenList), len(SendKeyList))AccessTokenList = AccessTokenList[:min_length]SendKeyList = SendKeyList[:min_length]print(f"🔧 共发现 {min_length} 个账号需要签到")# 按 SendKey 分组task_groups = defaultdict(list)for access_token, send_key in zip(AccessTokenList, SendKeyList):task_groups[send_key].append(access_token)print(f" 共分为 {len(task_groups)} 个通知组")# 顺序执行签到任务group_results = {}for send_key, tokens in task_groups.items():print(f"\n 开始处理 SendKey: {send_key[:5]}... 的 {len(tokens)} 个账号")results = []for i, token in enumerate(tokens):print(f" 处理第 {i+1}/{len(tokens)} 个账号...")# 执行签到result = sign_in(token)if result is not None:results.append(result)# 如果不是最后一个账号,则等待随机时间if i < len(tokens) - 1:wait_time = random.randint(5, 15)print(f"⏳ 等待 {wait_time} 秒后处理下一个账号...")time.sleep(wait_time)group_results[send_key] = results# 推送通知 - 只在有获取到金豆时才发送print("\n 开始检查是否需要发送通知...")notification_sent = Falsefor send_key, results in group_results.items():if results:content = "\n\n".join(results)print(f" 检测到有金豆获取,准备发送通知给 SendKey: {send_key[:5]}...")response = send_msg_by_server(send_key, "嘉立创签到汇总", content)if response and response.get('code') == 0:print(f" 通知发送成功!消息ID: {response.get('data', {}).get('pushid', '')}")notification_sent = Trueelse:error_msg = response.get('message') if response else '未知错误'print(f" 通知发送失败!错误: {error_msg}")else:print(f" SendKey: {send_key[:5]}... 组内无金豆获取,跳过通知")if not notification_sent:print(" 所有账号均未获取到金豆,无通知发送")# ======== 程序入口 ========if __name__ == '__main__':print(" 嘉立创自动签到任务开始")main()print(" 任务执行完毕")
该脚本为嘉立创自动签到 + 金豆统计 + server酱推送"的脚本。
支持 多账号,通过环境变量
TOKEN_LIST:存放多个账号的AccessTokenSEND_KEY_LIST:存放对应的 Server酱SendKey每个账号执行:
调用资产接口获取当前账号信息(含
customerCode、当前金豆数integralVoucher)调用签到接口,完成当天签到
如果是第七天特殊签到,调用第七天奖励接口
将 签到成功、获得金豆的结果 按通知分组汇总,通过 Server酱 推送到微信
若所有账号都没有获得金豆(比如都已签到过),则 不发送通知
通常配合 定时任务 使用,每天定时跑一遍,实现"无人值守自动签到 + 微信提醒"。
主要函数
1. mask_account(account)
作用:
对账号标识做脱敏,用于日志输出时隐藏敏感信息,例如把 12345678 变成 12****78。
2. mask_json_customer_code(data)
作用:
对一个 JSON 数据结构(字典 / 列表嵌套)进行递归脱敏,专门处理字段名为 customerCode 的值。
例如:1ABCDE8A 会变成 1xxxxx8A。
主要用于在调试/打印完整 JSON 时,避免泄露真实账号信息。3. send_msg_by_server(send_key, title, content)
作用:
通过 Server酱(api.ftqq.com) 发送通知消息。
入参:
send_key:当前这组账号绑定的 Server酱 keytitle:通知标题(本脚本里固定为"嘉立创签到汇总")content:通知正文(多行,包含该组内各账号签到结果)返回:Server酱接口的 JSON 响应结果,用来判断是否发送成功。
4. sign_in(access_token)
作用:
完成 单个账号 的完整签到流程,并返回一条可读的签到结果字符串(或 None)。
构造请求头
设置
X-JLC-AccessToken为当前账号的access_token设置一个 iPhone + 嘉立创 App 的
User-Agent伪装客户端获取资产信息(金豆、customerCode)
调用
gold_bean_url接口解析
data.customerCode(账号标识)与data.integralVoucher(当前金豆总数)执行签到
若
False且 message 提示"已经签到":打印"今日已签到",返回None若
False且其他错误:打印"签到失败 + 错误信息",返回None调用
url(签到接口)判断
success字段:处理签到成功结果
认为是 第七天签到特殊情况,调用
seventh_day_url领取第七天奖励若领取成功:返回 "第七天签到成功 + 当前金豆总数(原有 + 8)"
若领取失败:只打印提示,不返回消息
说明是普通签到,打印成功日志
返回一条字符串,如:
账号(1x****8A):获取X个金豆,当前总数:原有金豆 + XgainNum:本次签到获得的金豆数量status:签到状态从
data中取出:若
status > 0且gainNum有值且不为 0:若
status > 0但gainNum为 0:异常处理
网络异常:捕获
RequestException,打印网络错误JSON 结构缺少关键字段:捕获
KeyError其他未预料的异常:通用
Exception
这些情况下均返回None,表示该账号本轮没有可推送的信息。
5. main()
作用:
负责 多账号调度 + 结果按通知分组汇总 + 触发推送,是整个脚本的核心调度函数。
主要逻辑:
读取环境变量
TOKEN_LIST→ 拆分成AccessTokenListSEND_KEY_LIST→ 拆分成SendKeyList两者按逗号分隔,一一对应
参数检查
若没有任何 token:提示"请设置 TOKENS",直接退出
若没有任何 send_key:提示"请设置 SENDKEYS",直接退出
若长度不一致:按最短长度截断,保证一一对应
按 SendKey 分组账号
使用
defaultdict(list)相同
send_key的账号归为同一组,用于共用一条 Server酱通知顺序执行各组账号的签到
依次遍历该组内的每一个
access_token调用
sign_in(token)获取结果字符串每两个账号之间 随机 sleep 5~15 秒,模拟人工操作,减少被风控的可能
若返回非
None,说明该账号今天有新金豆,加入当前组的results对每个分组:
发送通知(有结果才发)
若列表非空:拼接成多行字符串,调用
send_msg_by_server发送微信通知若列表为空:说明该组账号今天没有新金豆(可能都签过到了),跳过通知
根据 Server酱返回 JSON 判断是否发送成功
对每个 send_key 对应的结果列表
results:总结提示
如果所有组都没有任何可推送信息,则打印:
所有账号均未获取到金豆,无通知发送
注意:
本文部分变量已做脱敏处理,仅用于测试和学习研究,禁止用于商业用途,不能保证其合法性,准确性,完整性和有效性,请根据情况自行判断。技术层面需要提供帮助,可以通过打赏的方式进行探讨。
没有评论:
发表评论