mirror of
https://github.com/yule153604/zglt_script.git
synced 2026-11-05 23:16:43 +08:00
feat(权益超市): 添加奖池查询、人机验证及浇花逻辑修复
- 新增 MarketRaffleState 全局奖池状态类,多账号共享查询结果 - 奖池查询改为抽奖完成后执行,仅作为信息展示 - 有效奖品判断:包含月卡/周卡/季卡,排除5G宽视界/沃视频,概率>0 - 新增 market_validate_captcha 人机验证自动处理 - 修复浇花任务逻辑:从只浇一次改为持续浇花直到完成目标次数 - 更新 README 文档
This commit is contained in:
1 parent
202f5f7ac8
commit
3835987dc2
2 files changed
+182
-13
No files matched your search
@@ -6,6 +6,10 @@
|
||||
|
||||
```text
|
||||
中国联通.py
|
||||
├── 📂 MarketRaffleState (全局奖池状态类)
|
||||
│ ├── __init__ .................... 初始化奖池状态/锁
|
||||
│ └── check_prizes ................ 查询奖池(全局单次,多账号共享)
|
||||
│
|
||||
├── 📂 Logger (日志管理类)
|
||||
│ ├── __init__ .................... 初始化日志前缀
|
||||
│ └── log ......................... 输出带时间戳的日志
|
||||
@@ -45,7 +49,11 @@
|
||||
│ │
|
||||
│ ├── 🛒 权益超市 (Market)
|
||||
│ ├── market_task ................. 超市任务入口
|
||||
│ ├── market_login ................ 超市登录
|
||||
│ ├── market_watering_task ........ 浇花任务(支持多次浇花直到完成)
|
||||
│ ├── market_watering ............. 执行浇花
|
||||
│ ├── market_raffle_task .......... 抽奖任务(抽奖后展示奖池信息)
|
||||
│ ├── market_validate_captcha ..... 人机验证处理
|
||||
│ └── market_raffle ............... 执行抽奖
|
||||
│ │
|
||||
│ ├── 🍇 新疆专区 (Xinjiang)
|
||||
@@ -66,6 +74,16 @@
|
||||
└── 🚀 main (主程序入口) ............ 并发调度所有账号任务
|
||||
```
|
||||
|
||||
## ✨ 功能特性
|
||||
|
||||
### 权益超市增强功能
|
||||
- **每日自动抽奖**: 无条件执行抽奖,不受奖池状态影响
|
||||
- **奖池信息展示**: 抽奖完成后展示今日奖池信息(概率>0的奖品)
|
||||
- **有效奖品识别**: 自动标记有效奖品(包含月卡/周卡/季卡,排除5G宽视界/沃视频)
|
||||
- **人机验证处理**: 抽奖触发人机验证时自动处理并继续抽奖
|
||||
- **浇花任务修复**: 支持多次浇花直到完成目标次数(如60次)
|
||||
- **全局奖池查询**: 多账号只查询一次奖池,共享结果,节省资源
|
||||
|
||||
### 3. 配置账号
|
||||
脚本通过环境变量 `chinaUnicomCookie` 获取用户登录信息。支持多账号,多个Cookie之间请使用 `@` 符号分隔。
|
||||
|
||||
@@ -94,21 +112,43 @@ python 中国联通.py
|
||||
### 5. 查看运行结果
|
||||
脚本运行后,将在控制台输出详细的执行日志。
|
||||
- **登录状态**: 显示登录成功/失败及脱敏后的手机号(如 `138****5678`)。
|
||||
- **任务进度**: 实时显示各个任务的执行情况(如“签到成功”、“获得0.87元立减金”)。
|
||||
- **抽奖结果**: 显示具体的奖品名称(如“5元话费券”、“未中奖”)。
|
||||
- **任务进度**: 实时显示各个任务的执行情况(如"签到成功"、"获得0.87元立减金")。
|
||||
- **奖池状态**: 抽奖完成后展示今日奖池信息及有效奖品。
|
||||
- **抽奖结果**: 显示具体的奖品名称(如"5元话费券"、"未中奖")。
|
||||
|
||||
#### 奖池查询输出示例
|
||||
```
|
||||
============================================================
|
||||
权益超市奖品池查询
|
||||
============================================================
|
||||
今日奖池共 16 个奖品:
|
||||
|
||||
✅ [01] 爱奇艺VIP月卡
|
||||
今日投放: 100 | 总库存: 5000 | 概率: 5.00%
|
||||
❌ [02] 5G宽视界黄金会员月卡
|
||||
今日投放: 50 | 总库存: 3000 | 概率: 3.00%
|
||||
❌ [03] 茶百道6元免配券
|
||||
今日投放: 5000 | 总库存: 0 | 概率: 15.00%
|
||||
...
|
||||
|
||||
============================================================
|
||||
结论: 当前已放水!有效奖品 3/16 个,可以抽奖
|
||||
============================================================
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
- **HTTP/2**: 为保证稳定性,脚本默认关闭了HTTP/2支持。
|
||||
- **异常处理**: 脚本内置了完善的异常捕获机制,单个任务的失败不会影响其他任务或账号的执行。
|
||||
- **隐私安全**: 所有敏感信息(如手机号)在日志输出时均会自动脱敏,保障用户隐私。
|
||||
- **奖池共享**: 权益超市奖池查询只执行一次,所有账号共享结果,避免重复请求。
|
||||
|
||||
## ❓ 常见问题与故障排除
|
||||
|
||||
### 1. 登录失败处理
|
||||
如果遇到登录失败的情况,请尝试以下步骤:
|
||||
1. 使用抓包工具获取本机实际的 `device_id` 和 `device_code`。
|
||||
2. 打开 `中国联通.py` 文件,找到 `online` 函数(约第 140 行)。
|
||||
2. 打开 `中国联通.py` 文件,找到 `online` 函数(约第 220 行)。
|
||||
3. 将代码中的 `device_id` 和 `device_code` 替换为抓包获取的实际值,保持一致。
|
||||
|
||||
### 2. 环境变量设置补充
|
||||
@@ -116,6 +156,11 @@ python 中国联通.py
|
||||
- 提取请求体或Header中的 `token_online` 值。
|
||||
- 将该值设置为环境变量 `chinaUnicomCookie`。
|
||||
|
||||
### 3. 权益超市相关
|
||||
- **浇花状态异常**: 已修复只浇花一次的问题,现在会持续浇花直到完成目标次数。
|
||||
- **奖池信息**: 抽奖完成后展示今日奖池,仅作为参考信息,不影响抽奖流程。
|
||||
- **人机验证**: 触发人机验证时会自动处理,无需手动干预。
|
||||
|
||||
## ⚠️ 免责声明
|
||||
|
||||
1. **仅供学习交流**:本项目仅供编程学习和技术交流使用,请勿用于任何商业用途。
|
||||
|
||||
@@ -30,6 +30,91 @@ ANOTHER_ENCRYPTION_KEY = "f4cd4ffeb5554586acf65ba7110534f5"
|
||||
SERVICE_LIFE = "wocareMBHServiceLife1"
|
||||
MIN_RETRIES = "1"
|
||||
|
||||
# ==================== Global Market Raffle State ====================
|
||||
# 全局奖池状态,多账号共享,只查询一次
|
||||
class MarketRaffleState:
|
||||
def __init__(self):
|
||||
self.checked = False # 是否已检查
|
||||
self.has_prizes = False # 是否有奖品可抽
|
||||
self.prizes = [] # 奖品列表
|
||||
self.lock = asyncio.Lock() # 异步锁
|
||||
|
||||
async def check_prizes(self, http_client, market_token):
|
||||
"""检查奖池状态,只执行一次"""
|
||||
async with self.lock:
|
||||
if self.checked:
|
||||
return self.has_prizes
|
||||
|
||||
print("\n" + "="*60)
|
||||
print("权益超市奖品池查询")
|
||||
print("="*60)
|
||||
|
||||
try:
|
||||
res = await http_client.request(
|
||||
'POST',
|
||||
'https://backward.bol.wo.cn/prod-api/promotion/home/raffleActivity/prizeList?id=12',
|
||||
headers={'Authorization': f'Bearer {market_token}'},
|
||||
data=''
|
||||
)
|
||||
|
||||
result = res['result']
|
||||
if result and result.get('code') == 200 and isinstance(result.get('data'), list):
|
||||
self.prizes = result['data']
|
||||
|
||||
# 筛选今日奖池(概率>0的奖品)
|
||||
today_prizes = [p for p in self.prizes if float(p.get('probability', 0)) > 0]
|
||||
total = len(today_prizes)
|
||||
print(f"今日奖池共 {total} 个奖品:\n")
|
||||
|
||||
# 有效奖品关键词
|
||||
include_keywords = ['月卡', '周卡', '月度', '季卡']
|
||||
exclude_keywords = ['5G宽视界', '沃视频']
|
||||
|
||||
valid_count = 0
|
||||
for i, prize in enumerate(today_prizes, 1):
|
||||
name = prize.get('name', '未知')
|
||||
try:
|
||||
daily_limit = int(prize.get('dailyPrizeLimit', 0))
|
||||
quantity = int(prize.get('quantity', 0))
|
||||
prob = float(prize.get('probability', 0))
|
||||
except:
|
||||
daily_limit = 0
|
||||
quantity = 0
|
||||
prob = 0.0
|
||||
|
||||
# 判断奖品是否有效:包含指定关键词、不含排除关键词、概率>0
|
||||
has_include = any(kw in name for kw in include_keywords)
|
||||
has_exclude = any(kw in name for kw in exclude_keywords)
|
||||
is_valid = has_include and not has_exclude and prob > 0
|
||||
|
||||
status = "✅" if is_valid else "❌"
|
||||
if is_valid:
|
||||
valid_count += 1
|
||||
|
||||
print(f" {status} [{i:02d}] {name}")
|
||||
print(f" 今日投放: {daily_limit} | 总库存: {quantity} | 概率: {prob*100:.2f}%")
|
||||
|
||||
print(f"\n{'='*60}")
|
||||
if valid_count > 0:
|
||||
self.has_prizes = True
|
||||
print(f"结论: 当前已放水!有效奖品 {valid_count}/{total} 个,可以抽奖")
|
||||
else:
|
||||
self.has_prizes = False
|
||||
print(f"结论: 当前未放水!无有效奖品,跳过抽奖")
|
||||
print("="*60 + "\n")
|
||||
else:
|
||||
print(f"奖品池查询失败: {result}")
|
||||
self.has_prizes = False
|
||||
except Exception as e:
|
||||
print(f"奖品池查询异常: {str(e)}")
|
||||
self.has_prizes = False
|
||||
|
||||
self.checked = True
|
||||
return self.has_prizes
|
||||
|
||||
# 全局奖池状态实例
|
||||
market_raffle_state = MarketRaffleState()
|
||||
|
||||
# ==================== Utils ====================
|
||||
class Logger:
|
||||
def __init__(self, prefix=""):
|
||||
@@ -707,13 +792,15 @@ class CustomUserService:
|
||||
result = res['result']
|
||||
if result and result.get('code') == 200:
|
||||
data = result.get('data', {})
|
||||
triggered = data.get('triggeredTime', 0)
|
||||
self.logger.log(f"浇花状态: {triggered}/{data.get('triggerTime')}")
|
||||
|
||||
if triggered == 0:
|
||||
triggered = int(data.get('triggeredTime', 0))
|
||||
trigger_time = int(data.get('triggerTime', 1))
|
||||
self.logger.log(f"浇花状态: {triggered}/{trigger_time}")
|
||||
|
||||
# 只要未完成全部次数就继续浇花
|
||||
if triggered < trigger_time:
|
||||
await self.market_watering()
|
||||
else:
|
||||
self.logger.log("今日已完成浇花")
|
||||
self.logger.log("浇花任务已全部完成")
|
||||
else:
|
||||
self.logger.log(f"获取浇花状态失败: {result}")
|
||||
except Exception as e:
|
||||
@@ -736,7 +823,29 @@ class CustomUserService:
|
||||
except Exception as e:
|
||||
self.logger.log(f"权益超市浇花异常: {str(e)}")
|
||||
|
||||
async def market_validate_captcha(self):
|
||||
"""人机验证"""
|
||||
try:
|
||||
res = await self.http.request(
|
||||
'POST',
|
||||
'https://backward.bol.wo.cn/prod-api/promotion/home/raffleActivity/validateCaptcha?id=12',
|
||||
headers={'Authorization': f'Bearer {self.market_token}'},
|
||||
data=''
|
||||
)
|
||||
|
||||
result = res['result']
|
||||
if result and result.get('code') == 200:
|
||||
self.logger.log("权益超市: 人机验证通过,继续抽奖")
|
||||
return await self.market_raffle()
|
||||
else:
|
||||
self.logger.log(f"权益超市: 人机验证失败 {result}")
|
||||
return False
|
||||
except Exception as e:
|
||||
self.logger.log(f"权益超市人机验证异常: {str(e)}")
|
||||
return False
|
||||
|
||||
async def market_raffle_task(self):
|
||||
"""权益超市抽奖任务"""
|
||||
try:
|
||||
y_gdtco4r = "0QDEN3AEqWlrU036_dbyBvP8.68dggpJ9Em3UEzaRWLwzFshel7nj1kEQxCiI.B_fIDMRTiEwAgmaG93mDGPLvSObw_.EMz5QG4wZp7CfpHt4y4WwUioW5NoIaRtTpiyNJN6ncFGlF607_haxxASNFfzwkxRl9XZq9UfHhGY.UCzebcoAawBTyh62PdjF.ka.HIygQuhbb16HitF0IfX_cdZc2wVsIUfLSnSYulZaLnoSo.7..nRFnMyydrDjQE4tfOT08heVczyyR6Bpn.ZazNvmNZD1EgfxCRTcQDUdHFb_XDfPbqvX2N0dtYdKgSV_1s5u8RlyUwXr1HlqKEpKb83uWfIPLaOpm3xFnKupjRqj1UoDz.vB0iRRkkYtAd8nPoY654drckOD7GEQQs79zJyMTZV_ExNU72MAqvZRdRUZZz8oho.t6WzyX5R2pOSrPRgO84hba3Ez52DbM_08n8qRm3bW1TaviGW1VEwQVH74R_Eo0pxoZDfHTbAGC3vAAzz7R8sqLVphu972XyCB72Ba1XGElelViYqGnG3p_SZ_LzzpQMJdGSa"
|
||||
res = await self.http.request(
|
||||
@@ -748,16 +857,19 @@ class CustomUserService:
|
||||
},
|
||||
data=''
|
||||
)
|
||||
|
||||
|
||||
result = res['result']
|
||||
count = 0
|
||||
if result and result.get('code') == 200:
|
||||
count = result.get('data', 0)
|
||||
self.logger.log(f"权益超市可抽奖次数: {count}")
|
||||
|
||||
|
||||
for i in range(count):
|
||||
await asyncio.sleep(3)
|
||||
await self.market_raffle()
|
||||
|
||||
# 抽奖完成后查询奖池信息(仅展示,全局只查一次)
|
||||
await market_raffle_state.check_prizes(self.http, self.market_token)
|
||||
except Exception as e:
|
||||
self.logger.log(f"权益超市抽奖任务异常: {str(e)}")
|
||||
|
||||
@@ -776,12 +888,24 @@ class CustomUserService:
|
||||
|
||||
result = res['result']
|
||||
if result and result.get('code') == 200:
|
||||
prize = result.get('data', {}).get('prizesName') or '未抽中'
|
||||
self.logger.log(f"权益超市抽奖: {prize}", notify=True)
|
||||
data = result.get('data', {})
|
||||
prize = data.get('prizesName') or '未抽中'
|
||||
message = data.get('message', '')
|
||||
if prize and prize != '未抽中':
|
||||
self.logger.log(f"权益超市抽奖: 恭喜抽中 {prize}", notify=True)
|
||||
else:
|
||||
self.logger.log(f"权益超市抽奖: {message or prize}")
|
||||
return True
|
||||
elif result and result.get('code') == 500:
|
||||
# 触发人机验证
|
||||
self.logger.log("权益超市: 触发人机验证,自动验证中...")
|
||||
return await self.market_validate_captcha()
|
||||
else:
|
||||
self.logger.log(f"权益超市抽奖失败: {result}")
|
||||
self.logger.log(f"权益超市抽奖失败: {result.get('message', result)}")
|
||||
return False
|
||||
except Exception as e:
|
||||
self.logger.log(f"权益超市抽奖异常: {str(e)}")
|
||||
return False
|
||||
|
||||
# ==================== Xinjiang (xj) ====================
|
||||
async def xj_task(self):
|
||||
|
||||
Reference in new issue
Block a user