新增-未验证

This commit is contained in:
XiaoGe-LiBai
2025-11-10 16:12:48 +08:00
parent ce6b704abe
commit 297407ba3c
11 changed files with 5462 additions and 0 deletions

View File

@@ -0,0 +1,43 @@
# 酒仙应用配置
class JiuxianConfig:
# 应用基本信息
APP_NAME = "酒仙"
VERSION = "9.2.13"
APP_KEY = "ad96ade2-b918-3e05-86b8-ba8c34747b0c"
DEVICE_ID = "ad96ade2-b918-3e05-86b8-ba8c34747b0c"
# API接口
LOGIN_URL = "https://newappuser.jiuxian.com/user/loginUserNamePassWd.htm"
MEMBER_INFO_URL = "https://newappuser.jiuxian.com/memberChannel/memberInfo.htm"
RECEIVE_REWARD_URL = "https://newappuser.jiuxian.com/memberChannel/receiveRewards.htm"
TASK_COMPLETE_URL = "https://shop.jiuxian.com/show/wap/addJinBi.htm"
SHARE_REPORT_URL = "https://log.umsns.com/share/multi_add/51ff1ac356240b6fb20a2156/-1/"
SIGN_URL = "https://newappuser.jiuxian.com/memberChannel/userSign.htm"
# 请求头
HEADERS = {
"User-Agent": "okhttp/3.14.9",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "newappuser.jiuxian.com",
"Connection": "Keep-Alive",
"Accept-Encoding": "gzip"
}
# 设备信息
DEVICE_INFO = {
"appVersion": VERSION,
"areaId": "500",
"channelCode": "0",
"cpsId": "xiaomi",
"deviceIdentify": DEVICE_ID,
"deviceType": "ANDROID",
"deviceTypeExtra": "0",
"equipmentType": "M2011K2C",
"netEnv": "wifi",
"screenReslolution": "1080x2297",
"supportWebp": "1",
"sysVersion": "14"
}
# Token存储文件路径
TOKEN_FILE = "/ql/data/scripts/jiuxian_tokens.json"

View File

@@ -0,0 +1,947 @@
"""
酒仙app/微信小程序签到脚本V1.1
邀请推广入口咱俩各得1000积分
https://img.meituan.net/portalweb/ba0be8b7b52975047a38682ec3070172251739.jpg
操作步骤:
打开上方链接
截图保存二维码
微信扫码参与活动
点击"立即领取"获得1000积分
请勿在0-1点之间运行
定时规则每天上午9点10分运行
10 9 * * *
脚本特色
· 自动完成每日签到 + 3个浏览任务
· 支持多账号批量运行
· 同时支持账号密码登录和Token登录
· 支持PushPlus微信推送通知
· 平均每日可获得约100金币
配置说明:
方式一:账号密码登录(多用户换行分割)
变量名jiuxian
格式:
手机号#密码
13800138000#123456
13900139000#abcdef
注意如使用账号密码登录请先在App中修改为自定义密码
方式二Token登录抓包微信小程序
变量名JX_TOKENS
获取方式:
抓包域名https://newappuser.jiuxian.com/
在请求参数中查找token值
格式:
token1
token2
token3
推送通知(可选)
变量名PUSHPLUS_TOKEN
在 PushPlus官网 获取Token用于接收运行结果推送
每日任务清单:
· 每日签到 [正常] - 10-70金币连续签到奖励更高
· 浏览任务1 [正常] - 20金币自动完成
· 浏览任务2 [正常] - 20金币自动完成
· 浏览任务3 [正常] - 20金币自动完成
· 分享任务 [待完善] - 100金币需要手动完成
收益估算:
· 基础收益每日约70-120金币
· 连续签到:每周额外奖励
· 月累计约3000金币
积分兑换
兑换内容:
· 多种实物商品
积分规则:
· 有效期:当年积分次年年底失效
· 清空机制:注意及时使用
#####################################################################
本脚本采用三层架构设计请下载以下3个文件并放在同一文件夹中
├── jiuxian_config.py # 配置层 - 管理应用配置、API接口和设备信息
├── jiuxian账密版.py # 业务逻辑层 - 主要的业务逻辑和任务执行流程
└── token_manager.py # 数据持久层 - 负责Token数据的存储和管理
使用步骤:
将三个文件下载到同一文件夹
配置环境变量jiuxian 或 JX_TOKENS
运行主程序task jiuxian账密版.py
####################################################################
-----------------------------------------------------------
免责声明
· 本脚本仅供学习交流使用,不得用于商业用途
· 使用者应对自己的行为负责,脚本作者不承担任何法律责任
· 请合理使用脚本,遵守相关平台规则
· 禁止将脚本用于任何违法违纪行为
· 如遇平台规则变更,请及时停止使用
· 下载或使用即代表同意以上声明
使用建议
· 建议设置合理的执行频率,避免对服务器造成压力
· 妥善保管账号信息,注意账号安全
· 关注平台规则变化,及时调整使用方式
· 如发现异常,请立即停止使用
风险提示
· 使用自动化脚本可能存在账号风险
· 请根据自身情况谨慎使用
· 如不确定是否合规,建议手动操作
------------------------------------------------------------
"""
import os
import json
import time
import random
import requests
from typing import Dict, List, Optional, Tuple
import urllib3
from jiuxian_config import JiuxianConfig
from token_manager import TokenManager
# 禁用SSL警告
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
class Jiuxian:
def __init__(self, username: str = None, password: str = None, token: str = None):
self.username = username
self.password = password
self.token = token
self.uid = None
self.nickname = None
self.task_token = None
self.session = requests.Session()
self.session.verify = False
self.token_manager = TokenManager(JiuxianConfig.TOKEN_FILE)
def get_phone_tail(self, phone: str = None) -> str:
"""获取手机尾号(脱敏处理)"""
if not phone:
phone = self.username or ""
if phone and len(phone) >= 4:
return f"******{phone[-4:]}"
return "****"
def load_saved_token(self) -> bool:
"""加载已保存的Token"""
if not self.username:
return False
token_data = self.token_manager.get_token(self.username)
if token_data and self.token_manager.is_token_valid(self.username):
self.token = token_data.get("token")
self.uid = token_data.get("uid")
self.nickname = token_data.get("nickname")
phone_tail = self.get_phone_tail()
print(f"🔑 加载已保存的Token: {self.nickname} ({phone_tail})")
return True
return False
def save_current_token(self):
"""保存当前Token信息"""
if self.token and self.uid and self.username:
token_data = {
"token": self.token,
"uid": self.uid,
"nickname": self.nickname,
"update_time": int(time.time())
}
self.token_manager.save_token(self.username, token_data)
phone_tail = self.get_phone_tail()
print(f"💾 保存Token信息: {self.nickname} ({phone_tail})")
def login_with_password(self) -> bool:
"""使用账号密码登录"""
try:
if not self.username or not self.password:
print("❌ 缺少账号或密码")
return False
login_data = JiuxianConfig.DEVICE_INFO.copy()
login_data.update({
"appKey": JiuxianConfig.APP_KEY,
"userName": self.username,
"passWord": self.password
})
response = self.session.post(
JiuxianConfig.LOGIN_URL,
data=login_data,
headers=JiuxianConfig.HEADERS,
timeout=30
)
if response.status_code == 200:
result = response.json()
if result.get("success") == "1":
user_info = result["result"]["userInfo"]
self.token = user_info["token"]
self.uid = user_info["uid"]
self.nickname = user_info["nickName"]
# 保存新的Token
self.save_current_token()
phone_tail = self.get_phone_tail()
print(f"✅ 密码登录成功: {self.nickname} ({phone_tail})")
return True
else:
phone_tail = self.get_phone_tail()
print(f"❌ 密码登录失败 ({phone_tail}): {result.get('errMsg', '未知错误')}")
# 登录失败时删除无效Token
if self.username:
self.token_manager.delete_token(self.username)
return False
else:
phone_tail = self.get_phone_tail()
print(f"❌ 登录请求失败 ({phone_tail}): HTTP {response.status_code}")
return False
except Exception as e:
phone_tail = self.get_phone_tail()
print(f"❌ 登录异常 ({phone_tail}): {str(e)}")
return False
def login_with_token(self) -> bool:
"""使用Token登录"""
try:
if not self.token:
print("❌ 未提供Token")
return False
# 直接使用提供的Token验证其有效性
phone_tail = self.get_phone_tail()
print(f"🔑 使用提供的Token登录 ({phone_tail})...")
return self.check_token_valid()
except Exception as e:
phone_tail = self.get_phone_tail()
print(f"❌ Token登录异常 ({phone_tail}): {str(e)}")
return False
def check_token_valid(self) -> bool:
"""检查当前Token是否有效"""
if not self.token:
return False
try:
# 通过获取会员信息来验证Token有效性
member_info = self.get_member_info()
if member_info:
# 如果获取到了会员信息说明Token有效
if not self.nickname and member_info.get('userInfo'):
self.nickname = member_info['userInfo'].get('nickName', '未知用户')
elif not self.nickname:
self.nickname = "Token用户"
phone_tail = self.get_phone_tail()
print(f"✅ Token验证成功: {self.nickname} ({phone_tail})")
return True
return False
except Exception:
return False
def smart_login(self) -> bool:
"""智能登录优先使用Token失败时使用密码登录"""
# 如果有直接提供的Token优先使用
if self.token:
phone_tail = self.get_phone_tail()
print(f"🔄 尝试使用提供的Token登录 ({phone_tail})...")
if self.login_with_token():
return True
else:
print("❌ 提供的Token无效尝试其他登录方式...")
# 1. 尝试加载已保存的Token需要用户名
if self.username and self.load_saved_token():
# 2. 验证Token是否仍然有效
if self.check_token_valid():
phone_tail = self.get_phone_tail()
print(f"✅ Token登录成功: {self.nickname} ({phone_tail})")
return True
else:
phone_tail = self.get_phone_tail()
print(f"🔄 保存的Token已过期 ({phone_tail}),尝试密码登录...")
# Token无效清除并重新登录
self.token_manager.delete_token(self.username)
# 3. 使用密码登录(需要用户名和密码)
if self.username and self.password:
password_login_success = self.login_with_password()
if password_login_success:
# 密码登录成功后立即获取会员信息来设置taskToken
self.get_member_info()
return True
phone_tail = self.get_phone_tail()
print(f"❌ 所有登录方式都失败了 ({phone_tail})")
return False
def get_member_info(self) -> Optional[Dict]:
"""获取会员信息包含任务列表和taskToken"""
if not self.token:
phone_tail = self.get_phone_tail()
print(f"❌ 请先登录 ({phone_tail})")
return None
try:
params = JiuxianConfig.DEVICE_INFO.copy()
params["token"] = self.token
params["appKey"] = JiuxianConfig.APP_KEY
response = self.session.get(
JiuxianConfig.MEMBER_INFO_URL,
params=params,
headers=JiuxianConfig.HEADERS,
timeout=30
)
if response.status_code == 200:
result = response.json()
if result.get("success") == "1":
member_data = result["result"]
# 保存taskToken到实例变量中
task_channel = member_data.get("taskChannel", {})
self.task_token = task_channel.get("taskToken", "")
if self.task_token:
phone_tail = self.get_phone_tail()
print(f"🔑 获取到taskToken ({phone_tail}): {self.task_token}")
else:
phone_tail = self.get_phone_tail()
print(f"⚠️ 未获取到taskToken ({phone_tail})")
return member_data
else:
# Token可能已过期
if result.get("errCode") in ["TOKEN_EXPIRED", "INVALID_TOKEN"]:
phone_tail = self.get_phone_tail()
print(f"❌ Token已过期 ({phone_tail})")
if self.username:
self.token_manager.delete_token(self.username)
return None
else:
phone_tail = self.get_phone_tail()
print(f"❌ 获取会员信息请求失败 ({phone_tail}): HTTP {response.status_code}")
return None
except Exception as e:
phone_tail = self.get_phone_tail()
print(f"❌ 获取会员信息异常 ({phone_tail}): {str(e)}")
return None
def check_in(self) -> Tuple[bool, str]:
"""每日签到"""
try:
if not self.token:
return False, "未登录"
params = JiuxianConfig.DEVICE_INFO.copy()
params["token"] = self.token
params["appKey"] = JiuxianConfig.APP_KEY
response = self.session.get(
JiuxianConfig.SIGN_URL,
params=params,
headers=JiuxianConfig.HEADERS,
timeout=30
)
if response.status_code == 200:
result = response.json()
if result.get("success") == "1":
sign_data = result["result"]
sign_days = sign_data.get("signDays", 0)
received_golds = sign_data.get("receivedGoldNums", 0)
will_get_golds = sign_data.get("willGetGolds", 0)
message = f"签到成功!连续签到{sign_days}天,获得{received_golds}金币"
if will_get_golds > 0:
message += f",明日可获得{will_get_golds}金币"
phone_tail = self.get_phone_tail()
print(f"{message} ({phone_tail})")
return True, message
else:
error_msg = result.get('errMsg', '未知错误')
phone_tail = self.get_phone_tail()
print(f"❌ 签到失败 ({phone_tail}): {error_msg}")
return False, error_msg
else:
error_msg = f"签到请求失败: HTTP {response.status_code}"
phone_tail = self.get_phone_tail()
print(f"{error_msg} ({phone_tail})")
return False, error_msg
except Exception as e:
error_msg = f"签到异常: {str(e)}"
phone_tail = self.get_phone_tail()
print(f"{error_msg} ({phone_tail})")
return False, error_msg
def complete_browse_task(self, task: Dict) -> bool:
"""完成浏览任务"""
try:
if not self.task_token:
phone_tail = self.get_phone_tail()
print(f"❌ 未获取到taskToken ({phone_tail}),无法完成任务")
return False
task_id = task["id"]
task_name = task["taskName"]
task_url = task["url"]
count_down = task.get("countDown", 15)
phone_tail = self.get_phone_tail()
print(f"🔄 开始浏览任务 ({phone_tail}): {task_name}, 需要浏览 {count_down}")
# 设置浏览页面的请求头
browse_headers = {
"User-Agent": "Mozilla/5.0 (Linux; Android 14; M2011K2C Build/UKQ1.230804.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/139.0.7258.158 Mobile Safari/537.36 jiuxianApp/9.2.13 from/ANDROID suptwebp/1 netEnv/wifi oadzApp lati/null long/null shopId/ areaId/500",
"Cookie": f"token={self.token}",
"Referer": "https://shop.jiuxian.com/",
"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.7",
"Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7"
}
print("📱 访问任务页面开始计时...")
# 1. 访问任务页面开始计时
browse_response = self.session.get(task_url, headers=browse_headers, timeout=30)
if browse_response.status_code != 200:
phone_tail = self.get_phone_tail()
print(f"❌ 任务页面访问失败 ({phone_tail}): HTTP {browse_response.status_code}")
return False
print("✅ 任务页面访问成功,开始计时...")
# 2. 等待浏览时间
wait_time = count_down + 5
print(f"⏰ 等待浏览计时 {wait_time} 秒...")
time.sleep(wait_time)
print("✅ 浏览完成,提交任务完成状态...")
# 3. 提交任务完成状态
complete_success = self.submit_task_completion(task_id, task_url)
if not complete_success:
return False
print("✅ 任务完成状态提交成功")
# 4. 领取金币奖励
print("💰 领取任务奖励...")
return self.receive_reward(task_id, task_name)
except Exception as e:
phone_tail = self.get_phone_tail()
print(f"❌ 浏览任务异常 ({phone_tail}): {str(e)}")
import traceback
print(f"详细错误: {traceback.format_exc()}")
return False
def complete_share_task(self, task: Dict) -> bool:
"""完成分享任务"""
try:
if not self.task_token:
phone_tail = self.get_phone_tail()
print(f"❌ 未获取到taskToken ({phone_tail}),无法完成任务")
return False
task_id = task["id"]
task_name = task["taskName"]
task_url = task["url"]
phone_tail = self.get_phone_tail()
print(f"🔄 开始分享任务 ({phone_tail}): {task_name}")
# 设置请求头
headers = {
"User-Agent": "Mozilla/5.0 (Linux; Android 14; M2011K2C Build/UKQ1.230804.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/139.0.7258.158 Mobile Safari/537.36 jiuxianApp/9.2.13 from/ANDROID suptwebp/1 netEnv/wifi oadzApp lati/null long/null shopId/ areaId/500",
"Cookie": f"token={self.token}",
"Referer": "https://shop.jiuxian.com/"
}
print("📱 访问分享页面...")
# 1. 访问分享页面
response = self.session.get(task_url, headers=headers, timeout=30)
if response.status_code != 200:
phone_tail = self.get_phone_tail()
print(f"❌ 分享页面访问失败 ({phone_tail}): HTTP {response.status_code}")
return False
print("✅ 分享页面访问成功")
# 2. 调用分享上报接口
print("📤 上报分享行为...")
share_success = self.report_share(task_url)
if not share_success:
print("❌ 分享上报失败")
return False
print("✅ 分享上报成功")
# 3. 提交任务完成状态
print("✅ 提交任务完成状态...")
complete_success = self.submit_task_completion(task_id, task_url)
if not complete_success:
return False
# 4. 领取金币奖励
print("💰 领取任务奖励...")
return self.receive_reward(task_id, task_name)
except Exception as e:
phone_tail = self.get_phone_tail()
print(f"❌ 分享任务异常 ({phone_tail}): {str(e)}")
return False
def report_share(self, task_url: str) -> bool:
"""上报分享行为(修复编码问题)"""
try:
boundary = "d38dd6cb-be16-4e1c-91ec-44369961499f"
headers = {
"User-Agent": "Dalvik/2.1.0 (Linux; U; Android 14; M2011K2C Build/UKQ1.230804.001)",
"Content-Type": f"multipart/form-data; boundary={boundary}",
"Host": "log.umsns.com"
}
# 使用字典构建表单数据
form_fields = {
"de": "M2011K2C",
"u_sharetype": "native",
"opid": "9",
"sdkv": "7.1.6",
"title": "酒仙网",
"mac": "no mac",
"dt": str(int(time.time() * 1000)),
"uid": "a90fd0967241099b5242c9a2ea2b97efod",
"sn": "",
"pcv": "3.0",
"os": "Android",
"ek": "-1",
"os_version": "14",
"en": "Wi-Fi",
"ak": "51ff1ac356240b6fb20a2156",
"url": task_url,
"ct": "酒等你来,发现一个超级好的活动,赶快买买买!",
"ftype": "0",
"imei": "a7204ced77696f16",
"sns": '{"qq":""}',
"furl": "http://m.jiuxian.com/mobile/android/update/picture/icon_launcher_new.png",
"to": '{"qq":""}',
"android_id": "2185ce8ea28df6ab",
"tp": "1",
"dc": "com.umeng.share"
}
# 自动生成multipart格式使用UTF-8编码
form_data = ""
for name, value in form_fields.items():
form_data += f"""--{boundary}
Content-Disposition: form-data; name="{name}"
Content-Type: text/plain; charset=UTF-8
{value}
"""
form_data += f"--{boundary}--"
# 显式使用UTF-8编码
response = self.session.post(
JiuxianConfig.SHARE_REPORT_URL,
data=form_data.encode('utf-8'),
headers=headers,
timeout=30
)
if response.status_code == 200:
result = response.json()
if result.get("st") == 200:
return True
print(f"❌ 分享上报失败: {response.text}")
return False
except Exception as e:
print(f"❌ 分享上报异常: {str(e)}")
return False
def submit_task_completion(self, task_id: int, task_url: str) -> bool:
"""提交任务完成状态(浏览和分享任务共用)"""
try:
headers = {
"User-Agent": "Mozilla/5.0 (Linux; Android 14; M2011K2C Build/UKQ1.230804.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/139.0.7258.158 Mobile Safari/537.36 jiuxianApp/9.2.13 from/ANDROID suptwebp/1 netEnv/wifi oadzApp lati/null long/null shopId/ areaId/500",
"Cookie": f"token={self.token}",
"Referer": task_url,
"X-Requested-With": "XMLHttpRequest",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
}
data = {
"taskId": str(task_id),
"taskToken": self.task_token
}
response = self.session.post(
JiuxianConfig.TASK_COMPLETE_URL,
data=data,
headers=headers,
timeout=30
)
if response.status_code == 200:
result = response.json()
if result.get("code") == 1:
return True
else:
phone_tail = self.get_phone_tail()
print(f"❌ 任务完成提交失败 ({phone_tail}): {result.get('msg', '未知错误')}")
else:
phone_tail = self.get_phone_tail()
print(f"❌ 任务完成提交请求失败 ({phone_tail}): HTTP {response.status_code}")
return False
except Exception as e:
phone_tail = self.get_phone_tail()
print(f"❌ 任务完成提交异常 ({phone_tail}): {str(e)}")
return False
def receive_reward(self, task_id: int, task_name: str) -> bool:
"""领取任务奖励"""
try:
params = JiuxianConfig.DEVICE_INFO.copy()
params["token"] = self.token
params["appKey"] = JiuxianConfig.APP_KEY
params["taskId"] = str(task_id)
response = self.session.get(
JiuxianConfig.RECEIVE_REWARD_URL,
params=params,
headers=JiuxianConfig.HEADERS,
timeout=30
)
if response.status_code == 200:
result = response.json()
if result.get("success") == "1":
reward_data = result["result"]
gold_num = reward_data.get("goldNum", 0)
phone_tail = self.get_phone_tail()
print(f"🎉 任务 '{task_name}' 完成 ({phone_tail}),获得 {gold_num} 金币")
return True
else:
phone_tail = self.get_phone_tail()
print(f"❌ 领取奖励失败 ({phone_tail}): {result.get('errMsg', '未知错误')}")
return False
else:
phone_tail = self.get_phone_tail()
print(f"❌ 领取奖励请求失败 ({phone_tail}): HTTP {response.status_code}")
return False
except Exception as e:
phone_tail = self.get_phone_tail()
print(f"❌ 领取奖励异常 ({phone_tail}): {str(e)}")
return False
def run_all_tasks(self) -> Dict:
"""执行所有任务"""
result = {
"username": self.username,
"phone_tail": self.get_phone_tail(),
"nickname": self.nickname,
"login_success": False,
"login_type": "unknown",
"check_in": {"success": False, "message": ""},
"tasks": [],
"member_info": {},
"today_gold": 0, # 今日获得金币
"total_gold": 0 # 总金币数
}
# 智能登录
login_success = self.smart_login()
if login_success:
result["login_success"] = True
result["nickname"] = self.nickname
if self.token and not self.username:
result["login_type"] = "direct_token"
else:
result["login_type"] = "token" if hasattr(self, 'token') and self.token else "password"
else:
result["login_success"] = False
return result
# 获取会员信息(只获取一次!)
member_info = self.get_member_info()
if not member_info:
return result
result["member_info"] = {
"gold_money": member_info.get("goldMoney", 0),
"is_sign_today": member_info.get("isSignTody", False),
"sign_days": member_info.get("signDays", 0),
"user_rank": member_info.get("userRank", "")
}
result["total_gold"] = member_info.get("goldMoney", 0)
# 确保taskToken已正确设置
if not self.task_token:
phone_tail = self.get_phone_tail()
print(f"❌ 未获取到taskToken ({phone_tail}),无法执行任务")
return result
print(f"🔑 使用taskToken: {self.task_token}")
# 处理签到(只有在未签到时才执行)
if not member_info.get("isSignTody"):
print("📅 执行签到...")
check_in_success, check_in_msg = self.check_in()
result["check_in"] = {"success": check_in_success, "message": check_in_msg}
# 如果签到成功,从消息中提取金币数
if check_in_success and "获得" in check_in_msg:
try:
gold_str = check_in_msg.split("获得")[1].split("金币")[0]
result["today_gold"] += int(gold_str)
except:
pass
time.sleep(random.randint(2, 4))
else:
result["check_in"] = {"success": True, "message": "今日已签到"}
print("📅 今日已签到,跳过签到")
# 处理任务
task_channel = member_info.get("taskChannel", {})
task_list = task_channel.get("taskList", [])
for task in task_list:
task_result = {
"id": task["id"],
"name": task["taskName"],
"type": task["taskType"],
"state": task["state"],
"gold_num": task.get("goldNum", 0),
"completed": False
}
# state: 0-未完成, 1-已完成未领取, 2-已完成已领取
if task["state"] == 0: # 未完成的任务
if task["taskType"] == 1: # 浏览任务
task_result["completed"] = self.complete_browse_task(task)
elif task["taskType"] == 2: # 分享任务
task_result["completed"] = self.complete_share_task(task)
# 如果任务完成,累加金币
if task_result["completed"]:
result["today_gold"] += task_result["gold_num"]
result["tasks"].append(task_result)
# 任务间短暂间隔
time.sleep(random.randint(2, 4))
return result
def send_pushplus_notification(token: str, title: str, content: str) -> bool:
"""发送PushPlus推送通知"""
try:
if not token:
print("❌ PushPlus Token未设置跳过推送")
return False
url = "https://www.pushplus.plus/send"
data = {
"token": token,
"title": title,
"content": content,
"template": "markdown"
}
response = requests.post(url, json=data, timeout=30)
if response.status_code == 200:
result = response.json()
if result.get("code") == 200:
print("✅ PushPlus推送发送成功")
return True
else:
print(f"❌ PushPlus推送失败: {result.get('msg', '未知错误')}")
return False
else:
print(f"❌ PushPlus推送请求失败: HTTP {response.status_code}")
return False
except Exception as e:
print(f"❌ PushPlus推送异常: {str(e)}")
return False
def generate_markdown_report(all_results: List[Dict]) -> str:
"""生成Markdown格式的报告"""
# 统计信息
total_users = len(all_results)
success_login_count = sum(1 for r in all_results if r["login_success"])
success_checkin_count = sum(1 for r in all_results if r.get("check_in", {}).get("success", False))
total_today_gold = sum(r.get("today_gold", 0) for r in all_results)
total_gold = sum(r.get("total_gold", 0) for r in all_results)
# 构建Markdown内容
content = f"""# 🍷 酒仙网任务执行报告
## 📊 统计概览
| 项目 | 数值 |
|------|------|
| 👥 用户总数 | {total_users} |
| ✅ 登录成功 | {success_login_count} |
| 📅 签到成功 | {success_checkin_count} |
| 🎯 今日获得金币 | {total_today_gold} |
| 💰 总金币数 | {total_gold} |
## 👤 用户详情
| 手机尾号 | 签到状态 | 任务状态 | 今日金币 | 总金币 |
|----------|----------|----------|----------|--------|
"""
# 添加每个用户的详情
for result in all_results:
phone_tail = result.get("phone_tail", "****")
nickname = result.get("nickname", "未知用户")
# 签到状态
check_in = result.get("check_in", {})
if check_in.get("success"):
sign_status = "✅ 成功"
else:
sign_status = "❌ 失败"
# 任务状态
tasks = result.get("tasks", [])
completed_tasks = sum(1 for t in tasks if t.get("completed", False))
total_tasks = len(tasks)
task_status = f"{completed_tasks}/{total_tasks}"
# 金币信息
today_gold = result.get("today_gold", 0)
total_gold_user = result.get("total_gold", 0)
content += f"| {phone_tail} ({nickname}) | {sign_status} | {task_status} | {today_gold} | {total_gold_user} |\n"
# 添加执行时间
exec_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
content += f"\n---\n**🕐 执行时间**: {exec_time}\n"
return content
def main():
"""主函数"""
# 获取环境变量
accounts_str = os.getenv("jiuxian", "")
tokens_str = os.getenv("JX_TOKENS", "")
pushplus_token = os.getenv("PUSHPLUS_TOKEN", "")
if not accounts_str and not tokens_str:
print("❌ 未找到账号配置,请检查环境变量 jiuxian 或 JX_TOKENS")
return
all_accounts = []
# 解析账号密码
if accounts_str:
for line in accounts_str.strip().split('\n'):
if '#' in line:
username, password = line.split('#', 1)
all_accounts.append(("account", username.strip(), password.strip()))
# 解析Token
if tokens_str:
for line in tokens_str.strip().split('\n'):
token = line.strip()
if token:
all_accounts.append(("token", None, token))
if not all_accounts:
print("❌ 未找到有效的账号配置")
return
print(f"🔍 找到 {len(all_accounts)} 个账号配置,开始执行任务...")
all_results = []
# 遍历所有账号执行任务
for i, (account_type, username, credential) in enumerate(all_accounts, 1):
print(f"\n{'='*50}")
phone_tail = "****" if not username else f"******{username[-4:]}" if len(username) >= 4 else "****"
print(f"🔄 开始处理账号 {i}: {phone_tail}")
if account_type == "account":
jiuxian = Jiuxian(username=username, password=credential)
else:
jiuxian = Jiuxian(token=credential)
result = jiuxian.run_all_tasks()
all_results.append(result)
print(f"✅ 账号 {i} 处理完成")
time.sleep(random.randint(3, 5)) # 账号间间隔
# 生成简单报告
print("\n" + "="*50)
print("📋 任务执行完成报告:")
success_count = sum(1 for r in all_results if r["login_success"])
print(f"✅ 成功执行: {success_count}/{len(all_accounts)} 个账号")
for i, result in enumerate(all_results, 1):
if result["login_success"]:
completed_tasks = sum(1 for t in result["tasks"] if t["completed"])
total_tasks = len(result["tasks"])
login_type = result.get('login_type', 'unknown')
phone_tail = result.get('phone_tail', '****')
print(f"账号 {i}: {result['nickname']} ({phone_tail}) - 完成任务: {completed_tasks}/{total_tasks}")
# 发送PushPlus推送
if pushplus_token:
print("\n📤 正在发送PushPlus推送通知...")
markdown_content = generate_markdown_report(all_results)
title = f"🍷 酒仙网任务报告 - {success_count}/{len(all_accounts)}成功"
send_pushplus_notification(pushplus_token, title, markdown_content)
else:
print("\n⚠️ 未设置PUSHPLUS_TOKEN环境变量跳过推送")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,51 @@
import json
import os
from typing import Dict, Optional
class TokenManager:
def __init__(self, token_file: str):
self.token_file = token_file
self.tokens = self._load_tokens()
def _load_tokens(self) -> Dict:
"""从文件加载Token数据"""
try:
if os.path.exists(self.token_file):
with open(self.token_file, 'r', encoding='utf-8') as f:
return json.load(f)
except Exception as e:
print(f"❌ 加载Token文件失败: {e}")
return {}
def _save_tokens(self):
"""保存Token数据到文件"""
try:
os.makedirs(os.path.dirname(self.token_file), exist_ok=True)
with open(self.token_file, 'w', encoding='utf-8') as f:
json.dump(self.tokens, f, ensure_ascii=False, indent=2)
except Exception as e:
print(f"❌ 保存Token文件失败: {e}")
def get_token(self, username: str) -> Optional[Dict]:
"""获取指定账号的Token信息"""
return self.tokens.get(username)
def save_token(self, username: str, token_data: Dict):
"""保存账号的Token信息"""
self.tokens[username] = {
"token": token_data.get("token"),
"uid": token_data.get("uid"),
"nickname": token_data.get("nickname"),
"update_time": token_data.get("update_time")
}
self._save_tokens()
def delete_token(self, username: str):
"""删除账号的Token信息"""
if username in self.tokens:
del self.tokens[username]
self._save_tokens()
def is_token_valid(self, username: str) -> bool:
"""检查Token是否有效"""
return username in self.tokens and self.tokens[username].get("token")

146
酒仙账密版/说明.txt Normal file
View File

@@ -0,0 +1,146 @@
邀请推广入口咱俩各得1000积分
https://img.meituan.net/portalweb/ba0be8b7b52975047a38682ec3070172251739.jpg
操作步骤:
打开上方链接
截图保存二维码
微信扫码参与活动
点击“立即领取“获得1000积分
请勿在0-1点之间运行
定时规则每天上午9点10分运行
10 9 * * *
脚本特色
· 自动完成每日签到 + 3个浏览任务
· 支持多账号批量运行
· 同时支持账号密码登录和Token登录
· 支持PushPlus微信推送通知
· 平均每日可获得约100金币
配置说明:
方式一:账号密码登录(多用户换行分割)
变量名jiuxian
格式:
手机号#密码
13800138000#123456
13900139000#abcdef
注意如使用账号密码登录请先在App或微信小程序中修改为自定义密码
方式二Token登录抓包微信小程序之前抓包的可以直接用变量名也不用改
变量名JX_TOKENS
获取方式:
抓包域名https://newappuser.jiuxian.com/
在请求参数中查找token值
格式:
token1
token2
token3
推送通知(可选)
变量名PUSHPLUS_TOKEN
在 PushPlus官网 获取Token用于接收运行结果推送
通知效果展示测试2个抓包3个账密登录的都正常。任务显示0是因为今天测试太多次都做完了
[img]https://img.meituan.net/portalweb/90e6ae964d32a53ba5e50cf43d65ba3b241586.png[/img]
[img]https://img.meituan.net/portalweb/631393743b31b47397308a6d4a7dbe6339174.png[/img]
每日任务清单:
· 每日签到 [正常] - 10-70金币连续签到奖励更高
· 浏览任务1 [正常] - 20金币自动完成
· 浏览任务2 [正常] - 20金币自动完成
· 浏览任务3 [正常] - 20金币自动完成
· 分享任务 [待完善] - 100金币需要手动完成运行分享任务时会报错无视即可
收益估算:
· 基础收益每日约70-120金币
· 连续签到:每周额外奖励
· 月累计约3000金币
积分兑换
兑换内容:
· 多种实物商品
[img]https://img.meituan.net/portalweb/6f739481b30ec3979b37bc172210d3ad883968.jpg[/img]
积分规则:
· 有效期:当年积分次年年底失效
· 清空机制:注意及时使用
#####################################################################
本脚本采用三层架构设计请下载以下3个文件并放在同一文件夹中
├── jiuxian_config.py # 配置层 - 管理应用配置、API接口和设备信息
├── jiuxian账密版.py # 业务逻辑层 - 主要的业务逻辑和任务执行流程
└── token_manager.py # 数据持久层 - 负责Token数据的存储和管理
使用步骤:
将三个文件下载到同一文件夹
配置环境变量jiuxian 或 JX_TOKENS
运行主程序task jiuxian账密版.py
####################################################################
-----------------------------------------------------------
免责声明
· 本脚本仅供学习交流使用,不得用于商业用途
· 使用者应对自己的行为负责,脚本作者不承担任何法律责任
· 请合理使用脚本,遵守相关平台规则
· 禁止将脚本用于任何违法违纪行为
· 如遇平台规则变更,请及时停止使用
· 下载或使用即代表同意以上声明
使用建议
· 建议设置合理的执行频率,避免对服务器造成压力
· 妥善保管账号信息,注意账号安全
· 关注平台规则变化,及时调整使用方式
· 如发现异常,请立即停止使用
风险提示
· 使用自动化脚本可能存在账号风险
· 请根据自身情况谨慎使用
· 如不确定是否合规,建议手动操作
------------------------------------------------------------