Continue seeded Qinglong script collection

This commit is contained in:
Hermes Agent
2026-05-24 05:33:05 +00:00
parent ca1a4275e4
commit b082da3fe1
392 changed files with 131619 additions and 7 deletions

View File

@@ -0,0 +1,777 @@
# Source: https://github.com/3ixi/CodeScripts/blob/main/lsym.py
# Raw: https://raw.githubusercontent.com/3ixi/CodeScripts/main/lsym.py
# Repo: 3ixi/CodeScripts
# Path: lsym.py
# UploadedAt: 2025-09-23T14:07:43+08:00
# SHA256: 055c5aab9a013320b4421b4b0c1d4ea2893639fbc2eee553a66dfb67bcd7d1e6
# Category: 微信小程序/抓包版
# Evidence: appid/openid/session_key/encryptedData等小程序字段
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
零食有鸣小程序签到脚本
脚本作者3iXi
创建时间2025/09/04
此脚本需要配合iPad协议服务使用
小程序:零食有鸣
"""
import time
import json
import re
from typing import Optional, Dict, List
try:
import httpx
except ImportError:
print("错误: 需要安装 httpx[http2] 依赖")
exit(1)
import getCode
# 可以在这里指定门店ID如果为空则自动获取注册时的门店ID
STORE_ID = ""
class LsymSignin:
"""零食有鸣小程序签到类"""
def __init__(self):
"""初始化签到客户端"""
self.base_url = "https://api-pub.lsym.cn"
self.app_id = "wx295a967684523cdd"
self.client = httpx.Client(http2=True, timeout=30.0, verify=False)
self.headers = {
"host": "api-pub.lsym.cn",
"appid": "wx295a967684523cdd",
"authorization": "",
"tenantid": "1001",
"xweb_xhr": "1",
"devicelanguage": "zh-cn",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x63090a13) UnifiedPCWindowsWechat(0xf254101e) XWEB/16389",
"accept": "*/*",
"content-type": "application/json",
"version": "3.1.0",
"devicemodel": "android",
"sec-fetch-site": "cross-site",
"sec-fetch-mode": "cors",
"sec-fetch-dest": "empty",
"referer": "https://servicewechat.com/wx295a967684523cdd/73/page-frame.html",
"accept-encoding": "gzip, deflate, br",
"accept-language": "zh-CN,zh;q=0.9",
"priority": "u=1, i"
}
self.access_token = None
self.member_id = None
self.lottery_activity_id = None
self.store_id = STORE_ID
def check_response(self, data: dict, operation: str) -> bool:
"""
检查响应是否成功
Args:
data (dict): 响应数据
operation (str): 操作名称
Returns:
bool: 是否成功
"""
if data.get("code") != 200:
print(f"{operation}失败:{data.get('msg', '未知错误')}")
return False
return True
def login(self, code: str) -> bool:
"""
用户登录
Args:
code (str): 微信小程序登录code
Returns:
bool: 登录是否成功
"""
url = f"{self.base_url}/scrm/member-identity/front/miniapp/silentLogin"
payload = {"loginType":0,"code":code}
try:
json_payload = json.dumps(payload, separators=(',', ':'))
headers = self.headers.copy()
headers["Content-Length"] = str(len(json_payload))
response = self.client.post(url, content=json_payload, headers=headers)
response.raise_for_status()
data = response.json()
if not self.check_response(data, "登录"):
return False
login_data = data.get("data", {})
self.access_token = login_data.get("accessToken")
self.member_id = login_data.get("memberId")
mobile = login_data.get("mobile", "")
if self.access_token and self.member_id:
self.headers["authorization"] = self.access_token
print("登录成功")
return True
else:
print("登录失败未获取到token或memberId")
return False
except Exception as e:
print(f"登录请求失败: {e}")
return False
def get_task_list(self) -> Optional[List[Dict]]:
"""
获取任务列表
Returns:
Optional[List[Dict]]: 任务列表None表示获取失败
"""
url = f"{self.base_url}/scrm/marketing/front/task/batchGetTaskList"
try:
response = self.client.get(url, headers=self.headers)
response.raise_for_status()
data = response.json()
if not self.check_response(data, "获取任务列表"):
return None
tasks = data.get("data", [])
filtered_tasks = []
for task in tasks:
join_detail = task.get("joinDetailVO", {})
task_state = join_detail.get("taskState")
task_type = task.get("taskType")
if task_type == 8 and task_state in [1, 2]:
filtered_tasks.append(task)
return filtered_tasks
except Exception as e:
print(f"获取任务列表请求失败: {e}")
return None
def register_task(self, activity_id: str, activity_name: str) -> bool:
"""
领取任务
Args:
activity_id (str): 活动ID
activity_name (str): 活动名称
Returns:
bool: 是否成功
"""
url = f"{self.base_url}/scrm/marketing/front/task/registerJoin"
params = {"activityId": activity_id}
try:
response = self.client.get(url, params=params, headers=self.headers)
response.raise_for_status()
data = response.json()
if self.check_response(data, f"领取任务【{activity_name}"):
print(f"任务【{activity_name}】领取成功")
return True
return False
except Exception as e:
print(f"领取任务【{activity_name}】请求失败: {e}")
return False
def visit_page(self, activity_id: str, activity_name: str) -> bool:
"""
提交任务浏览记录
Args:
activity_id (str): 活动ID
activity_name (str): 活动名称
Returns:
bool: 是否成功
"""
url = f"{self.base_url}/scrm/marketing/front/task/visitPage"
payload = {
"activityId": activity_id,
"taskType": 8
}
try:
json_payload = json.dumps(payload, separators=(',', ':'))
headers = self.headers.copy()
headers["Content-Length"] = str(len(json_payload))
response = self.client.post(url, content=json_payload, headers=headers)
response.raise_for_status()
data = response.json()
if self.check_response(data, f"浏览任务【{activity_name}"):
print(f"任务【{activity_name}】浏览成功")
return True
return False
except Exception as e:
print(f"浏览任务【{activity_name}】请求失败: {e}")
return False
def receive_prize(self, activity_id: str, activity_name: str) -> bool:
"""
领取任务奖励
Args:
activity_id (str): 活动ID
activity_name (str): 活动名称
Returns:
bool: 是否成功
"""
url = f"{self.base_url}/scrm/marketing/front/task/receivePrize"
params = {"activityId": activity_id}
try:
response = self.client.get(url, params=params, headers=self.headers)
response.raise_for_status()
data = response.json()
if self.check_response(data, f"领取奖励【{activity_name}"):
print(f"任务【{activity_name}】奖励领取成功")
return True
return False
except Exception as e:
print(f"领取奖励【{activity_name}】请求失败: {e}")
return False
def get_lottery_activity_id(self) -> Optional[str]:
"""
获取抽奖活动ID
Returns:
Optional[str]: 抽奖活动IDNone表示获取失败
"""
if self.lottery_activity_id:
return self.lottery_activity_id
url = f"{self.base_url}/scrm/cms/front/page/redirect/all"
payload = {}
try:
json_payload = json.dumps(payload, separators=(',', ':'))
headers = self.headers.copy()
headers["Content-Length"] = str(len(json_payload))
response = self.client.post(url, content=json_payload, headers=headers)
response.raise_for_status()
data = response.json()
if not self.check_response(data, "获取抽奖活动ID"):
return None
activities = data.get("data", [])
for activity in activities:
original_title = activity.get("originalTitle", "")
if "" in original_title and "停用" not in original_title:
redirect_url = activity.get("redirectUrl", "")
try:
redirect_data = json.loads(redirect_url)
params = redirect_data.get("params", {})
activity_id = params.get("id")
if activity_id:
self.lottery_activity_id = activity_id
return activity_id
except json.JSONDecodeError:
continue
print("未找到有效的抽奖活动")
return None
except Exception as e:
print(f"获取抽奖活动ID请求失败: {e}")
return None
def get_lottery_quota_rules(self, activity_id: str) -> Optional[Dict]:
"""
获取抽奖任务规则
Args:
activity_id (str): 抽奖活动ID
Returns:
Optional[Dict]: 抽奖任务规则None表示获取失败
"""
url = f"{self.base_url}/scrm/marketing/front/activity/lottery-wheel/get-user-exchange-quota-rule-list"
params = {"activityId": activity_id}
try:
response = self.client.get(url, params=params, headers=self.headers)
response.raise_for_status()
data = response.json()
if not self.check_response(data, "获取抽奖任务规则"):
return None
return data.get("data", {})
except Exception as e:
print(f"获取抽奖任务规则请求失败: {e}")
return None
def add_browse_record(self, activity_id: str, link_path: str, second: int, title: str) -> bool:
"""
添加浏览记录
Args:
activity_id (str): 抽奖活动ID
link_path (str): 链接路径
second (int): 浏览秒数
title (str): 页面标题
Returns:
bool: 是否成功
"""
url = f"{self.base_url}/scrm/marketing/front/activity/lottery-wheel/add-browse-record"
payload = {
"activityId": activity_id,
"memberId": self.member_id,
"linkPath": link_path,
"second": second
}
try:
json_payload = json.dumps(payload, separators=(',', ':'))
headers = self.headers.copy()
headers["Content-Length"] = str(len(json_payload))
response = self.client.post(url, content=json_payload, headers=headers)
response.raise_for_status()
data = response.json()
if self.check_response(data, f"浏览【{title}{second}"):
print("任务完成")
return True
return False
except Exception as e:
print(f"添加浏览记录请求失败: {e}")
return False
def submit_share_task(self, activity_id: str) -> bool:
"""
提交分享任务
Args:
activity_id (str): 抽奖活动ID
Returns:
bool: 是否成功
"""
url = f"{self.base_url}/scrm/marketing/front/activity/lottery-wheel/user-exchange-quota-operate"
payload = {
"activityId": activity_id,
"type": 2,
"versionId": "7"
}
try:
json_payload = json.dumps(payload, separators=(',', ':'))
headers = self.headers.copy()
headers["Content-Length"] = str(len(json_payload))
response = self.client.post(url, content=json_payload, headers=headers)
response.raise_for_status()
data = response.json()
if self.check_response(data, "分享任务"):
print("分享任务完成")
return True
return False
except Exception as e:
print(f"提交分享任务请求失败: {e}")
return False
def get_lottery_quota(self, activity_id: str) -> Optional[int]:
"""
查询抽奖次数
Args:
activity_id (str): 抽奖活动ID
Returns:
Optional[int]: 抽奖次数None表示获取失败
"""
url = f"{self.base_url}/scrm/marketing/front/activity/lottery-wheel/get-user-lottery-quota"
params = {"activityId": activity_id}
try:
response = self.client.get(url, params=params, headers=self.headers)
response.raise_for_status()
data = response.json()
if not self.check_response(data, "查询抽奖次数"):
return None
quota = data.get("data", 0)
print(f"可用抽奖次数{quota}")
return quota
except Exception as e:
print(f"查询抽奖次数请求失败: {e}")
return None
def ensure_store_id(self) -> bool:
"""
确保门店ID已设置如未设置则从会员信息中获取
Returns:
bool: 是否成功获取门店ID
"""
if self.store_id:
return True
member_info = self.get_member_info()
if not member_info:
print("获取会员信息失败无法获取门店ID")
return False
register_store_id = member_info.get("registerStoreId")
register_store_name = member_info.get("registerStoreName", "")
if not register_store_id:
print("会员信息中未找到注册门店ID")
return False
self.store_id = register_store_id
print(f"获取到注册门店信息:{register_store_name}({register_store_id})")
return True
def draw_lottery(self, activity_id: str) -> Optional[Dict]:
"""
抽奖
Args:
activity_id (str): 抽奖活动ID
Returns:
Optional[Dict]: 抽奖结果None表示抽奖失败
"""
if not self.ensure_store_id():
print("门店ID获取失败无法进行抽奖")
return None
url = f"{self.base_url}/scrm/marketing/front/activity/lottery-wheel/prize-draw"
payload = {
"activityId": activity_id,
"versionId": "7"
}
try:
json_payload = json.dumps(payload, separators=(',', ':'))
headers = self.headers.copy()
headers["Content-Length"] = str(len(json_payload))
headers["storeid"] = self.store_id
response = self.client.post(url, content=json_payload, headers=headers)
response.raise_for_status()
data = response.json()
if not self.check_response(data, "抽奖"):
return None
return data.get("data", {})
except Exception as e:
print(f"抽奖请求失败: {e}")
return None
def get_member_info(self) -> Optional[Dict]:
"""
获取会员信息
Returns:
Optional[Dict]: 会员信息None表示获取失败
"""
url = f"{self.base_url}/scrm/member/front/getCurrentMember"
try:
response = self.client.get(url, headers=self.headers)
response.raise_for_status()
data = response.json()
if not self.check_response(data, "获取会员信息"):
return None
return data.get("data", {})
except Exception as e:
print(f"获取会员信息请求失败: {e}")
return None
def get_coupons(self) -> Optional[List[Dict]]:
"""
获取未使用的优惠券
Returns:
Optional[List[Dict]]: 优惠券列表None表示获取失败
"""
url = f"{self.base_url}/scrm/marketing/front/memberCoupon/page"
params = {
"currPage": 1,
"pageSize": 20,
"couponState": 2
}
try:
response = self.client.get(url, params=params, headers=self.headers)
response.raise_for_status()
data = response.json()
if not self.check_response(data, "获取优惠券"):
return None
records = data.get("data", {}).get("records", [])
return records
except Exception as e:
print(f"获取优惠券请求失败: {e}")
return None
def process_tasks(self) -> bool:
"""
处理任务流程
Returns:
bool: 是否处理成功
"""
# 1. 获取任务列表
tasks = self.get_task_list()
if not tasks:
print("未获取到有效任务")
return False
# 2. 处理任务
for task in tasks:
activity_id = task.get("activityId")
activity_name = task.get("activityName")
join_detail = task.get("joinDetailVO", {})
task_state = join_detail.get("taskState")
# 检查必要字段
if not activity_id or not activity_name:
continue
if task_state == 1: # 未领取
if not self.register_task(activity_id, activity_name):
continue
if task_state in [1, 2]: # 未领取或待完成
# 提交浏览记录
if not self.visit_page(activity_id, activity_name):
continue
# 领取奖励
if not self.receive_prize(activity_id, activity_name):
continue
elif task_state == 3: # 已完成,直接领取奖励
self.receive_prize(activity_id, activity_name)
return True
def process_lottery(self) -> bool:
"""
处理抽奖流程
Returns:
bool: 是否处理成功
"""
# 1. 获取抽奖活动ID
activity_id = self.get_lottery_activity_id()
if not activity_id:
return False
# 2. 获取抽奖任务规则
quota_rules = self.get_lottery_quota_rules(activity_id)
if not quota_rules:
return False
# 3. 处理浏览任务
browse_task = quota_rules.get("browseDesignatedPage", {})
if browse_task.get("valid") and browse_task.get("state") == 1:
thresholds = browse_task.get("thresholds", [])
for threshold in thresholds:
if threshold.get("valid"):
link_url = threshold.get("linkUrl", "")
second = threshold.get("second", 10)
try:
link_data = json.loads(link_url)
title = link_data.get("title", "")
path = link_data.get("path", "")
print(f"可做任务:浏览【{title}{second}")
self.add_browse_record(activity_id, path, second, title)
except json.JSONDecodeError:
continue
# 4. 处理分享任务
share_task = quota_rules.get("share", {})
if share_task.get("valid") and share_task.get("state") == 1:
self.submit_share_task(activity_id)
# 5. 查询抽奖次数并抽奖
time.sleep(2)
quota = self.get_lottery_quota(activity_id)
if quota and quota > 0:
for i in range(quota):
draw_result = self.draw_lottery(activity_id)
if draw_result:
state = draw_result.get("state", 1)
if state == 0: # 中奖
prize = draw_result.get("prize", {})
prize_name = prize.get("prizeName", "")
prize_object = prize.get("prizeObject", {})
coupons = prize_object.get("coupons", [])
if coupons:
count = coupons[0].get("count", 1)
print(f"{i+1}次抽奖抽中了{prize_name}x{count}")
else:
print(f"{i+1}次抽奖抽中了{prize_name}")
if i < quota - 1:
time.sleep(1)
return True
def process_account(self, nick_name: str, code: str) -> bool:
"""
处理单个账号的签到流程
Args:
nick_name (str): 账号昵称
code (str): 微信小程序登录code
Returns:
bool: 是否处理成功
"""
print(f"\n开始处理账号: {nick_name}")
# 1. 登录
if not self.login(code):
print(f"账号 {nick_name} 登录失败")
return False
# 2. 处理任务
self.process_tasks()
# 3. 处理抽奖
self.process_lottery()
# 4. 获取会员信息和积分
member_info = self.get_member_info()
if member_info:
mobile = member_info.get("mobile", "")
balance = member_info.get("balance", "0")
# 手机号打码
if len(mobile) >= 7:
masked_mobile = mobile[:3] + "****" + mobile[7:]
else:
masked_mobile = mobile
print(f"{masked_mobile}当前有{balance}积分")
# 5. 获取优惠券信息
coupons = self.get_coupons()
if coupons:
print("未使用优惠券:")
for coupon in coupons:
coupon_name = coupon.get("couponName", "")
effective_time_end = coupon.get("effectiveTimeEnd", "")
print(f"{coupon_name}({effective_time_end}过期)")
else:
print("暂无未使用优惠券")
return True
def close(self):
"""关闭HTTP客户端"""
self.client.close()
def reset_session(self):
"""
重置/清理会话数据
"""
try:
self.client.close()
except Exception:
pass
self.client = httpx.Client(http2=True, timeout=30.0, verify=False)
self.access_token = None
self.member_id = None
self.headers["authorization"] = ""
self.store_id = STORE_ID
print("已清理会话数据,准备下一个账号...")
def main():
"""主函数"""
try:
print("正在获取登录Code...")
app_id = "wx295a967684523cdd"
codes = getCode.get_wechat_codes(app_id)
if not codes:
print("未获取到任何在线账号的Code")
return
print(f"获取到 {len(codes)} 个账号的Code")
signin = LsymSignin()
try:
for i, (nick_name, code) in enumerate(codes.items(), 1):
print(f"\n{'='*50}")
print(f"处理第 {i}/{len(codes)} 个账号")
print(f"{'='*50}")
try:
signin.process_account(nick_name, code)
except Exception as e:
print(f"处理账号 {nick_name} 时发生错误: {e}")
signin.reset_session()
if i < len(codes):
print(f"等待2秒后处理下一个账号...")
time.sleep(2)
finally:
signin.close()
print("\n所有账号处理完成")
except Exception as e:
print(f"脚本执行失败: {e}")
if __name__ == "__main__":
main()