什么值得买

网页端登录

F12–network–headers–cookie—_ckguid=~~~smzdm_id=8500

复制_ckguid=~~~smzdm_id=8500

环境变量-创建变量-名称填写SMZDM_COOKIE,值填写复制的cookie

脚本随意设置为smzdm.py

"""
cron: 39 17 * * *
new Env('什么值得买签到')
"""

import requests, json, time, hashlib, os, random, re
from datetime import datetime, timedelta

# ---------------- 统一通知模块加载 ----------------
hadsend = False
send = None
try:
    from notify import send
    hadsend = True
    print("✅ 已加载notify.py通知模块")
except ImportError:
    print("⚠️  未加载通知模块,跳过通知功能")

# 随机延迟配置
max_random_delay = int(os.getenv("MAX_RANDOM_DELAY", "3600"))
random_signin = os.getenv("RANDOM_SIGNIN", "true").lower() == "true"

def format_time_remaining(seconds):
    """格式化时间显示"""
    if seconds <= 0:
        return "立即执行"
    hours, minutes = divmod(seconds, 3600)
    minutes, secs = divmod(minutes, 60)
    if hours > 0:
        return f"{hours}小时{minutes}分{secs}秒"
    elif minutes > 0:
        return f"{minutes}分{secs}秒"
    else:
        return f"{secs}秒"

def wait_with_countdown(delay_seconds, task_name):
    """带倒计时的随机延迟等待"""
    if delay_seconds <= 0:
        return
    print(f"{task_name} 需要等待 {format_time_remaining(delay_seconds)}")
    remaining = delay_seconds
    while remaining > 0:
        if remaining <= 10 or remaining % 10 == 0:
            print(f"{task_name} 倒计时: {format_time_remaining(remaining)}")
        sleep_time = 1 if remaining <= 10 else min(10, remaining)
        time.sleep(sleep_time)
        remaining -= sleep_time

def notify_user(title, content):
    """统一通知函数"""
    if hadsend:
        try:
            send(title, content)
            print(f"✅ 通知发送完成: {title}")
        except Exception as e:
            print(f"❌ 通知发送失败: {e}")
    else:
        print(f"📢 {title}\n📄 {content}")

def get_user_info(cookie):
    """获取用户基本信息"""
    try:
        print("👤 正在获取用户信息...")
        infourl = 'https://zhiyou.smzdm.com/user/'
        headers = {
            'Host': 'zhiyou.smzdm.com',
            'Accept': '*/*',
            'Connection': 'keep-alive',
            'Cookie': cookie,
            'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148/smzdm 10.4.6 rv:130.1 (iPhone 13; iOS 15.6; zh_CN)/iphone_smzdmapp/10.4.6/wkwebview/jsbv_1.0.0',
            'Accept-Language': 'zh-CN,zh-Hans;q=0.9',
            'Referer': 'https://m.smzdm.com/',
            'Accept-Encoding': 'gzip, deflate, br'
        }
        
        response_info = requests.get(url=infourl, headers=headers, timeout=15).text
        
        # 解析用户信息
        name_match = re.search(r'<a href="https://zhiyou.smzdm.com/user"> (.*?) </a>', response_info)
        level_match = re.search(r'<img src=".*?/level/(\d+).png.*?"', response_info)
        gold_match = re.search(r'<div class="assets-part assets-gold">.*?<span class="assets-part-element assets-num">(.*?)</span>', response_info, re.S)
        silver_match = re.search(r'<div class="assets-part assets-prestige">.*?<span class="assets-part-element assets-num">(.*?)</span>', response_info, re.S)
        
        name = name_match.group(1).strip() if name_match else "未知用户"
        level = level_match.group(1) if level_match else "0"
        gold = gold_match.group(1).strip() if gold_match else "0"
        silver = silver_match.group(1).strip() if silver_match else "0"
        
        print(f"👤 用户: {name} (VIP{level})")
        print(f"💰 金币: {gold}, 🪙 碎银: {silver}")
        
        return name, level, gold, silver
    except Exception as e:
        print(f"❌ 获取用户信息失败: {e}")
        return "未知用户", "0", "0", "0"

def get_monthly_exp(cookie):
    """获取本月经验"""
    try:
        print("📊 正在获取本月经验...")
        current_month = datetime.now().strftime('%Y-%m')
        total_exp = 0
        
        for page in range(1, 4):  # 查询前3页
            url = f'https://zhiyou.m.smzdm.com/user/exp/ajax_log?page={page}'
            headers = {
                'Host': 'zhiyou.m.smzdm.com',
                'Accept': 'application/json, text/plain, */*',
                'Connection': 'keep-alive',
                'Cookie': cookie,
                'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148/smzdm 10.4.40 rv:137.6 (iPhone 13; iOS 15.6; zh_CN)/iphone_smzdmapp/10.4.40/wkwebview/jsbv_1.0.0',
                'Accept-Language': 'zh-CN,zh-Hans;q=0.9',
                'Referer': 'https://zhiyou.m.smzdm.com/user/exp/',
                'Accept-Encoding': 'gzip, deflate, br'
            }
            
            resp = requests.get(url=url, headers=headers, timeout=10)
            if resp.status_code != 200:
                break
                
            result = resp.json()
            rows = result.get('data', {}).get('rows', [])
            
            if not rows:
                break
                
            for row in rows:
                exp_date = row.get('creation_date', '')[:7]
                if exp_date == current_month:
                    total_exp += int(row.get('add_exp', 0))
                elif exp_date < current_month:
                    # 如果日期小于当前月份,说明已经查完了
                    return total_exp
            
            # 添加请求间隔
            time.sleep(random.uniform(0.5, 1.5))
        
        print(f"📊 本月经验: {total_exp}")
        return total_exp
    except Exception as e:
        print(f"❌ 获取月度经验失败: {e}")
        return 0

def smzdm_signin(cookie, index):
    """什么值得买签到 - 单个账号"""
    print(f"\n==== 开始第{index}个帐号签到 ====")
    
    try:
        # 0. 获取用户信息
        name, level, gold, silver = get_user_info(cookie)
        
        # 1. 获取Token
        print("🤖 正在获取Token...")
        ts = int(round(time.time() * 1000))
        url = 'https://user-api.smzdm.com/robot/token'
        headers = {
            'Host': 'user-api.smzdm.com',
            'Content-Type': 'application/x-www-form-urlencoded',
            'Cookie': cookie,
            'User-Agent': 'smzdm_android_V10.4.1 rv:841 (22021211RC;Android12;zh)smzdmapp',
        }
        data = {
            "f": "android",
            "v": "10.4.1",
            "weixin": 1,
            "time": ts,
            "sign": hashlib.md5(bytes(f'f=android&time={ts}&v=10.4.1&weixin=1&key=apr1$AwP!wRRT$gJ/q.X24poeBInlUJC', encoding='utf-8')).hexdigest().upper()
        }
        
        html = requests.post(url=url, headers=headers, data=data, timeout=15)
        
        # 检查HTTP状态码
        if html.status_code != 200:
            error_msg = f"❌ 账号{index}: HTTP请求失败,状态码: {html.status_code}"
            print(error_msg)
            return error_msg, False
        
        # 尝试解析JSON
        try:
            result = html.json()
        except json.JSONDecodeError as e:
            error_msg = f"❌ 账号{index}: 响应不是有效的JSON格式 - {str(e)}"
            print(error_msg)
            return error_msg, False
        
        # 检查API返回的错误码
        error_code = result.get('error_code')
        error_msg_api = result.get('error_msg', '未知错误')
        
        if str(error_code) != "0":
            error_msg = f"❌ 账号{index}: Token获取失败 - 错误码: {error_code}, 错误信息: {error_msg_api}"
            print(error_msg)
            return error_msg, False
        
        # 检查是否有data字段和token
        if 'data' not in result or 'token' not in result['data']:
            error_msg = f"❌ 账号{index}: 响应中缺少token数据 - {result}"
            print(error_msg)
            return error_msg, False
            
        token = result['data']['token']
        print(f"✅ Token获取成功")

        # 2. 执行签到
        print("🎯 正在执行签到...")
        Timestamp = int(round(time.time() * 1000))
        sign_data = {
            "f": "android",
            "v": "10.4.1",
            "sk": "ierkM0OZZbsuBKLoAgQ6OJneLMXBQXmzX+LXkNTuKch8Ui2jGlahuFyWIzBiDq/L",
            "weixin": 1,
            "time": Timestamp,
            "token": token,
            "sign": hashlib.md5(bytes(f'f=android&sk=ierkM0OZZbsuBKLoAgQ6OJneLMXBQXmzX+LXkNTuKch8Ui2jGlahuFyWIzBiDq/L&time={Timestamp}&token={token}&v=10.4.1&weixin=1&key=apr1$AwP!wRRT$gJ/q.X24poeBInlUJC', encoding='utf-8')).hexdigest().upper()
        }
        
        # 签到请求
        url_signin = 'https://user-api.smzdm.com/checkin'
        html_signin = requests.post(url=url_signin, headers=headers, data=sign_data, timeout=15)
        
        if html_signin.status_code != 200:
            error_msg = f"❌ 账号{index}: 签到HTTP请求失败,状态码: {html_signin.status_code}"
            print(error_msg)
            return error_msg, False
        
        try:
            signin_result = html_signin.json()
        except json.JSONDecodeError as e:
            error_msg = f"❌ 账号{index}: 签到响应不是有效的JSON格式 - {str(e)}"
            print(error_msg)
            return error_msg, False
        
        signin_msg = signin_result.get('error_msg', '签到状态未知')
        signin_code = signin_result.get('error_code', -1)
        print(f"🎯 签到状态: {signin_msg}")
        
        # 3. 获取签到奖励
        print("🎁 正在查询签到奖励...")
        url_reward = 'https://user-api.smzdm.com/checkin/all_reward'
        html_reward = requests.post(url=url_reward, headers=headers, data=sign_data, timeout=15)
        
        reward_info = ""
        if html_reward.status_code == 200:
            try:
                reward_result = html_reward.json()
                
                if str(reward_result.get('error_code')) == "0" and reward_result.get('data'):
                    normal_reward = reward_result["data"].get("normal_reward", {})
                    if normal_reward:
                        reward_content = normal_reward.get("reward_add", {}).get("content", "无奖励")
                        sub_title = normal_reward.get("sub_title", "无连续签到信息")
                        reward_info = f"\n🎁 签到奖励: {reward_content}\n📅 连续签到: {sub_title}"
                        print(f"🎁 签到奖励: {reward_content}")
                        print(f"📅 连续签到: {sub_title}")
            except Exception as e:
                print(f"⚠️ 奖励信息解析失败: {e}")
        else:
            print(f"⚠️ 奖励查询失败,状态码: {html_reward.status_code}")
        
        # 4. 获取本月经验
        monthly_exp = get_monthly_exp(cookie)
        
        # 5. 组合结果消息
        final_msg = f"""什么值得买签到结果

👤 账号: 第{index}个账号 ({name})
⭐ 等级: VIP{level}
💰 金币: {gold}
🪙 碎银: {silver}
📊 本月经验: {monthly_exp}

🎯 签到状态: {signin_msg}
📊 状态码: {signin_code}{reward_info}

🕐 签到时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"""
        
        # 判断是否成功
        is_success = (str(signin_code) == "0" or 
                     "成功" in signin_msg or 
                     "已经" in signin_msg or 
                     "重复" in signin_msg or
                     "已签" in signin_msg)
        
        print(f"{'✅ 签到成功' if is_success else '❌ 签到失败'}")
        return final_msg, is_success

    except requests.exceptions.Timeout:
        error_msg = f"❌ 账号{index}: 请求超时,网络连接可能有问题"
        print(error_msg)
        return error_msg, False
    except requests.exceptions.ConnectionError:
        error_msg = f"❌ 账号{index}: 网络连接错误,无法连接到服务器"
        print(error_msg)
        return error_msg, False
    except Exception as e:
        error_msg = f"❌ 账号{index}: 签到异常 - {str(e)}"
        print(error_msg)
        return error_msg, False

def main():
    """主程序入口"""
    print(f"==== 什么值得买签到开始 - {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} ====")
    
    # 随机延迟(整体延迟)
    if random_signin:
        delay_seconds = random.randint(0, max_random_delay)
        if delay_seconds > 0:
            signin_time = datetime.now() + timedelta(seconds=delay_seconds)
            print(f"🎲 随机模式: 延迟 {format_time_remaining(delay_seconds)} 后开始")
            print(f"⏰ 预计开始时间: {signin_time.strftime('%H:%M:%S')}")
            wait_with_countdown(delay_seconds, "什么值得买签到")

    # 获取环境变量
    SMZDM_COOKIE_env = os.getenv("SMZDM_COOKIE")
    
    if not SMZDM_COOKIE_env:
        error_msg = "❌ 未找到SMZDM_COOKIE环境变量,请设置什么值得买Cookie"
        print(error_msg)
        notify_user("什么值得买签到失败", error_msg)
        return

    # 解析多账号Cookie(使用换行符分割,支持Cookie中包含&符号)
    SMZDM_COOKIEs = [c.strip() for c in SMZDM_COOKIE_env.replace('\r\n', '\n').split('\n') if c.strip()]
    print(f"📝 共发现 {len(SMZDM_COOKIEs)} 个账号")
    
    success_count = 0
    total_count = len(SMZDM_COOKIEs)
    
    for i, cookie in enumerate(SMZDM_COOKIEs):
        try:
            # 账号间随机等待
            if i > 0:
                delay = random.uniform(5, 15)
                print(f"⏱️  随机等待 {delay:.1f} 秒后处理下一个账号...")
                time.sleep(delay)
            
            # 执行签到
            result_msg, is_success = smzdm_signin(cookie.strip(), i + 1)
            
            if is_success:
                success_count += 1
            
            # 发送单个账号通知
            title = f"什么值得买账号{i + 1}签到{'成功' if is_success else '失败'}"
            notify_user(title, result_msg)
            
        except Exception as e:
            error_msg = f"❌ 账号{i + 1}: 处理异常 - {str(e)}"
            print(error_msg)
            notify_user(f"什么值得买账号{i + 1}签到失败", error_msg)
    
    # 发送汇总通知
    if total_count > 1:
        summary_msg = f"""什么值得买签到汇总

📊 总计处理: {total_count}个账号
✅ 签到成功: {success_count}个账号
❌ 签到失败: {total_count - success_count}个账号
📈 成功率: {success_count/total_count*100:.1f}%
🕐 完成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"""
        
        notify_user("什么值得买签到汇总", summary_msg)
    
    print(f"\n==== 什么值得买签到完成 - 成功{success_count}/{total_count} - {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} ====")

if __name__ == "__main__":
    main()

定时任务:task smzdm.py 定时规则:35 08 * * * 每天早上8点35运行