酒仙每日任务 py 脚本

酒仙每日任务 py 脚本

import os
import json
import time
import random
import requests
import sys
from typing import Dict, List, Optional, Tuple
import urllib3

# 禁用SSL警告
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

# 应用配置
class JiuxianConfig:
    APP_NAME = "酒仙"
    VERSION = "9.2.13"
    APP_KEY = "1ba8b341-5a56-49dc-8ee3-92b32db7fc21"

    # 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"
    SIGN_URL = "https://newappuser.jiuxian.com/memberChannel/userSign.htm"
    LOTTERY_DRAW_URL = "https://h5market2.jiuxian.com/drawObject"
    DRAW_PAGE_URL = "https://h5market2.jiuxian.com/draw.htm"

    # 小程序设备信息
    MINI_PROGRAM_INFO = {
        'appKey': '1ba8b341-5a56-49dc-8ee3-92b32db7fc21',
        'appVersion': '9.2.12',
        'apiVersion': '1.0',
        'areaId': '2048',
        'channelCode': '0, 1',
        'appChannel': 'xiaochengxu',
        'deviceType': 'XIAOCHENGXU',
        'supportWebp': '2',
        'longi': '115.80287868923611',
        'lati': '28.155340440538193',
        'screenReslolution': '412x915',
        'sysVersion': 'Android 14'
    }

    # APP设备信息
    APP_DEVICE_INFO = {
        "appVersion": "9.2.13",
        "areaId": "500",
        "channelCode": "0", 
        "cpsId": "xiaomi",
        "deviceIdentify": "ad96ade2-b918-3e05-86b8-ba8c34747b0c",
        "deviceType": "ANDROID",
        "deviceTypeExtra": "0",
        "equipmentType": "M2011K2C",
        "netEnv": "wifi",
        "screenReslolution": "1080x2297",
        "supportWebp": "1",
        "sysVersion": "14",
        "appKey": "ad96ade2-b918-3e05-86b8-ba8c34747b0c"
    }

    # 小程序请求头
    MINI_PROGRAM_HEADERS = {
        "Host": "newappuser.jiuxian.com",
        "Connection": "keep-alive",
        "content-type": "application/json",
        "secure": "false",
        "charset": "utf-8",
        "Referer": "https://servicewechat.com/wx244a18142bb0c78a/144/page-frame.html",
        "User-Agent": "Mozilla/5.0 (Linux; Android 14; M2011K2C Build/UKQ1.230804.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/138.0.7258.158 Mobile Safari/537.36 XWEB/1380267 MMWEBSDK/20250904 MMWEBID/6819 MicroMessenger/8.0.64.2940(0x2800403C) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android",
        "Accept-Encoding": "gzip, deflate, br"
    }

    # APP请求头
    APP_HEADERS = {
        "User-Agent": "okhttp/3.14.9",
        "Content-Type": "application/x-www-form-urlencoded",
        "Host": "newappuser.jiuxian.com",
        "Connection": "Keep-Alive",
        "Accept-Encoding": "gzip"
    }

    @staticmethod
    def get_token_file():
        script_dir = os.path.dirname(os.path.abspath(__file__))
        return os.path.join(script_dir, "jiuxian_tokens.json")

# Token管理器
class TokenManager:
    def __init__(self, token_file: str):
        self.token_file = token_file
        self.tokens = self._load_tokens()

    def _load_tokens(self) -> Dict:
        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):
        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]:
        return self.tokens.get(username)

    def save_token(self, username: str, token_data: Dict):
        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):
        if username in self.tokens:
            del self.tokens[username]
            self._save_tokens()

    def is_token_valid(self, username: str) -> bool:
        return username in self.tokens and self.tokens[username].get("token")

# 抽奖模块
class JiuxianLotteryModule:
    def __init__(self, session: requests.Session, token: str, username: str = None):
        self.session = session
        self.token = token
        self.username = username
        self.user_agent = 'Mozilla/5.0 (Linux; Android 14; M2011K2C Build/UKQ1.230804.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/138.0.7258.158 Mobile Safari/537.36 XWEB/1380283 MMWEBSDK/20250904 MMWEBID/2537 MicroMessenger/8.0.64.2940(0x2800403E) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 miniProgram/wx244a18142bb0c78a'

    def get_phone_tail(self) -> str:
        if self.username and len(self.username) >= 4:
            return self.username[-4:]
        return "未知"

    def lottery_draw(self) -> Tuple[bool, str]:
        try:
            phone_tail = self.get_phone_tail()
            print(f"🎰 开始抽奖 ({phone_tail})...")

            # 访问抽奖页面
            draw_url = JiuxianConfig.DRAW_PAGE_URL
            params = {'id': '8e8b7f5386194798ab1ae7647f4af6ba', 'token': self.token}
            draw_headers = {
                'User-Agent': self.user_agent,
                'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/wxpic,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
                'X-Requested-With': 'com.tencent.mm',
                'Sec-Fetch-Site': 'none',
                'Sec-Fetch-Mode': 'navigate',
                'Sec-Fetch-User': '?1',
                'Sec-Fetch-Dest': 'document',
                'Accept-Encoding': 'gzip, deflate, br, zstd',
                'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7'
            }
            response = self.session.get(draw_url, params=params, headers=draw_headers, verify=False)
            print(f"🎰 抽奖页面访问 ({phone_tail}): {response.status_code}")

            # 执行抽奖
            lottery_url = JiuxianConfig.LOTTERY_DRAW_URL
            current_time = int(time.time() * 1000)
            data = {
                'id': '8e8b7f5386194798ab1ae7647f4af6ba',
                'isOrNotAlert': 'false',
                'orderSn': '',
                'advId': '',
                'time': str(current_time)
            }
            lottery_headers = {
                'User-Agent': self.user_agent,
                'Accept': '*/*',
                'X-Requested-With': 'XMLHttpRequest',
                'Content-Type': 'application/x-www-form-urlencoded',
                'Origin': 'https://h5market2.jiuxian.com',
                'Sec-Fetch-Site': 'same-origin',
                'Sec-Fetch-Mode': 'cors',
                'Sec-Fetch-Dest': 'empty',
                'Referer': f'https://h5market2.jiuxian.com/draw.htm?id=8e8b7f5386194798ab1ae7647f4af6ba&token={self.token}',
                'Accept-Encoding': 'gzip, deflate, br, zstd',
                'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7'
            }
            response = self.session.post(lottery_url, data=data, headers=lottery_headers, verify=False)

            if response.status_code != 200:
                print(f"❌ 抽奖请求失败 ({phone_tail}): HTTP {response.status_code}")
                return False, "请求失败"

            try:
                result = response.json()
            except:
                print(f" 抽奖返回数据解析失败 ({phone_tail})")
                return False, "数据解析失败"

            print(f"🎰 抽奖返回数据: {result}")

            # 解析结果
            if 'luck' in result:
                if result['luck'] is False:
                    print(f" 今日已抽奖 ({phone_tail})")
                    return False, "已抽过"
                else:
                    luck_info = result.get('luck', {})
                    luck_name = luck_info.get('luckname', '未知')
                    state = luck_info.get('State', 0)
                    object_id = luck_info.get('ObjectID', 0)

                    if state == 1 and object_id == 0:
                        print(f" 抽奖完成 ({phone_tail}): {luck_name}")
                        return False, luck_name
                    elif state == 1 and object_id > 0:
                        print(f"🎉 中奖 ({phone_tail}): {luck_name}")
                        return True, luck_name
                    else:
                        print(f"❓ 未知抽奖结果 ({phone_tail}): state={state}, object_id={object_id}, prize={luck_name}")
                        return False, luck_name
            else:
                print(f"❌ 抽奖失败 ({phone_tail})")
                return False, "失败"

        except Exception as e:
            phone_tail = self.get_phone_tail()
            print(f"❌ 抽奖异常 ({phone_tail}): {str(e)}")
            return False, "异常"

# 青龙推送模块
class QLNotifier:
    @staticmethod
    def send(title: str, content: str):
        try:
            from notify import send as ql_send
            ql_send(title, content)
            print(f"✅ 青龙通知发送成功: {title}")
        except ImportError:
            print(f"📢 {title}\n📝 {content}")
        except Exception as e:
            print(f"❌ 发送通知异常: {str(e)}")

# 主业务类
class Jiuxian:
    def __init__(self, username: str = None, password: str = None):
        self.username = username
        self.password = password
        self.token = None
        self.uid = None
        self.nickname = None
        self.task_token = None
        self.session = requests.Session()
        self.session.verify = False
        self.token_manager = TokenManager(JiuxianConfig.get_token_file())
        self.lottery_module = None
        self.continuous_sign_days = 0
        self.total_gold = 0
        self.today_gold = 0
        self.is_signed_today = False

    def get_phone_tail(self, phone: str = None) -> str:
        phone = phone or self.username or ""
        return phone[-4:] if (phone and len(phone) >= 4) else "未知"

    def load_saved_token(self) -> bool:
        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")
            print(f"🔑 加载已保存的Token: {self.nickname} ({self.get_phone_tail()})")
            return True
        return False

    def save_current_token(self):
        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)
            print(f"💾 保存Token信息: {self.nickname} ({self.get_phone_tail()})")

    def login_with_password(self) -> bool:
        try:
            if not self.username or not self.password:
                print("❌ 缺少账号或密码")
                return False

            login_data = JiuxianConfig.APP_DEVICE_INFO.copy()
            login_data.update({"userName": self.username, "passWord": self.password})

            response = self.session.post(
                JiuxianConfig.LOGIN_URL,
                data=login_data,
                headers=JiuxianConfig.APP_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"]
                    self.lottery_module = JiuxianLotteryModule(self.session, self.token, self.username)
                    self.save_current_token()
                    print(f"✅ 密码登录成功: {self.nickname} ({self.get_phone_tail()})")
                    return True
                else:
                    print(f"❌ 密码登录失败 ({self.get_phone_tail()}): {result.get('errMsg', '未知错误')}")
                    self.token_manager.delete_token(self.username)
                    return False
            else:
                print(f"❌ 登录请求失败 ({self.get_phone_tail()}): HTTP {response.status_code}")
                return False

        except Exception as e:
            print(f"❌ 登录异常 ({self.get_phone_tail()}): {str(e)}")
            return False

    def check_token_valid(self) -> bool:
        if not self.token:
            return False
        try:
            member_info = self.get_member_info()
            if member_info:
                if not self.nickname:
                    self.nickname = member_info['userInfo'].get('nickName', '未知用户') or "Token用户"
                print(f"✅ Token验证成功: {self.nickname} ({self.get_phone_tail()})")
                return True
            return False
        except Exception:
            return False

    def smart_login(self) -> bool:
        if self.username and self.load_saved_token():
            if self.check_token_valid():
                print(f"✅ Token登录成功: {self.nickname} ({self.get_phone_tail()})")
                self.lottery_module = JiuxianLotteryModule(self.session, self.token, self.username)
                return True
            else:
                print(f"🔄 保存的Token已过期 ({self.get_phone_tail()}),尝试密码登录...")
                self.token_manager.delete_token(self.username)

        if self.username and self.password:
            if self.login_with_password():
                self.get_member_info()
                return True

        print(f"❌ 所有登录方式都失败了 ({self.get_phone_tail()})")
        return False

    def get_member_info(self) -> Optional[Dict]:
        if not self.token:
            print(f"❌ 请先登录 ({self.get_phone_tail()})")
            return None

        try:
            params = JiuxianConfig.MINI_PROGRAM_INFO.copy()
            params["token"] = self.token
            params["equipmentType"] = json.dumps({
                "deviceAbi": "arm64-v8a",
                "benchmarkLevel": 33,
                "cpuType": "Venus based on Qualcomm Technologies, Inc SM8350",
                "system": "Android 14",
                "memorySize": 11228,
                "abi": "arm64-v8a",
                "model": "M2011K2C",
                "brand": "Xiaomi",
                "platform": "android"
            })

            response = self.session.get(
                JiuxianConfig.MEMBER_INFO_URL,
                params=params,
                headers=JiuxianConfig.MINI_PROGRAM_HEADERS,
                timeout=30
            )

            if response.status_code == 200:
                result = response.json()
                if result.get("success") == "1":
                    member_data = result["result"]
                    task_channel = member_data.get("taskChannel", {})
                    self.task_token = task_channel.get("taskToken", "")
                    self.total_gold = member_data.get("goldMoney", 0)
                    self.is_signed_today = member_data.get("isSignTody", False)
                    self.continuous_sign_days = member_data.get("signDays", 0)

                    if self.task_token:
                        print(f"🔑 获取到taskToken ({self.get_phone_tail()}): {self.task_token}")
                    print(f"💰 当前总金币: {self.total_gold}")
                    print(f"📅 今日是否签到: {'是' if self.is_signed_today else '否'}")
                    print(f"📅 累计签到天数: {self.continuous_sign_days}")
                    return member_data
                else:
                    if result.get("errCode") in ["TOKEN_EXPIRED", "INVALID_TOKEN"]:
                        print(f"❌ Token已过期 ({self.get_phone_tail()})")
                        self.token_manager.delete_token(self.username)
                    else:
                        print(f"❌ 获取会员信息失败 ({self.get_phone_tail()}): {result.get('errMsg', '未知错误')}")
            else:
                print(f"❌ 会员信息请求失败 ({self.get_phone_tail()}): HTTP {response.status_code}")
            return None
        except Exception as e:
            print(f"❌ 获取会员信息异常 ({self.get_phone_tail()}): {str(e)}")
            return None

    def user_sign(self) -> Tuple[bool, int]:
        if not self.token:
            print(f"❌ 请先登录 ({self.get_phone_tail()})")
            return False, 0

        try:
            params = JiuxianConfig.MINI_PROGRAM_INFO.copy()
            params["token"] = self.token
            params["equipmentType"] = json.dumps({
                "deviceAbi": "arm64-v8a",
                "benchmarkLevel": 33,
                "cpuType": "Venus based on Qualcomm Technologies, Inc SM8350",
                "system": "Android 14",
                "memorySize": 11228,
                "abi": "arm64-v8a",
                "model": "M2011K2C",
                "brand": "Xiaomi",
                "platform": "android"
            })

            response = self.session.get(
                JiuxianConfig.SIGN_URL,
                params=params,
                headers=JiuxianConfig.MINI_PROGRAM_HEADERS,
                timeout=30
            )

            if response.status_code == 200:
                result = response.json()
                if result.get("success") == "1":
                    sign_result = result["result"]
                    earned_gold = sign_result.get("receivedGoldNums", 0)
                    new_sign_days = sign_result.get("signDays", 0)
                    will_get_golds = sign_result.get("willGetGolds", 0)
                    self.continuous_sign_days = new_sign_days
                    
                    print(f"✅ 签到成功 ({self.get_phone_tail()})")
                    print(f"   📅 累计签到天数: {new_sign_days}")
                    print(f"   💰 获得金币: {earned_gold}")
                    print(f"   💰 将获得金币: {will_get_golds}")
                    return True, earned_gold
                else:
                    err_msg = result.get("errMsg", "未知错误")
                    print(f"❌ 签到失败 ({self.get_phone_tail()}): {err_msg}")
                    if "已签到" in err_msg or "重复" in err_msg:
                        print(f"ℹ️ 今日已签到过 ({self.get_phone_tail()})")
                        self.get_member_info()
                        return True, 0
            else:
                print(f"❌ 签到请求失败 ({self.get_phone_tail()}): HTTP {response.status_code}")
            return False, 0
        except Exception as e:
            print(f"❌ 签到异常 ({self.get_phone_tail()}): {str(e)}")
            return False, 0

    def complete_browse_task_original(self, task_id: str, task_name: str) -> Tuple[bool, int]:
        try:
            if not self.task_token:
                print(f"❌ 未获取到taskToken ({self.get_phone_tail()}),无法完成任务")
                return False, 0

            print(f"🔄 开始浏览任务 ({self.get_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/",
                "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"
            }
            task_url = f"https://shop.jiuxian.com/show/wap/act/viewShopActivity.htm?viewType=2&actId=7418&taskToken={self.task_token}&taskId={task_id}&token={self.token}"
            browse_response = self.session.get(task_url, headers=headers, timeout=30)
            if browse_response.status_code != 200:
                print(f"❌ 任务页面访问失败 ({self.get_phone_tail()}): HTTP {browse_response.status_code}")
                return False, 0

            # 等待浏览计时
            wait_time = 15
            print(f"⏰ 等待浏览计时 {wait_time} 秒...")
            time.sleep(wait_time)

            # 提交任务完成状态
            print("✅ 浏览完成,提交任务完成状态...")
            complete_headers = {
                "User-Agent": headers["User-Agent"],
                "Cookie": headers["Cookie"],
                "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=complete_headers,
                timeout=30
            )

            if response.status_code == 200:
                result = response.json()
                if result.get("code") == 1:
                    print("✅ 任务完成状态提交成功")

                    # 领取奖励
                    params = JiuxianConfig.MINI_PROGRAM_INFO.copy()
                    params["token"] = self.token
                    params["taskId"] = str(task_id)
                    reward_response = self.session.get(
                        JiuxianConfig.RECEIVE_REWARD_URL,
                        params=params,
                        headers=JiuxianConfig.MINI_PROGRAM_HEADERS,
                        timeout=30
                    )

                    if reward_response.status_code == 200:
                        reward_result = reward_response.json()
                        if reward_result.get("success") == "1":
                            reward_data = reward_result["result"]
                            gold_num = reward_data.get("goldNum", 20)
                            print(f"🎉 任务 '{task_name}' 完成 ({self.get_phone_tail()}),获得 {gold_num} 金币")
                            return True, gold_num
                        else:
                            print(f"❌ 领取奖励失败 ({self.get_phone_tail()}): {reward_result.get('errMsg', '未知错误')}")
                            return False, 0
                    else:
                        print(f"❌ 领取奖励请求失败 ({self.get_phone_tail()}): HTTP {reward_response.status_code}")
                        return False, 0
                else:
                    print(f"❌ 任务完成提交失败 ({self.get_phone_tail()}): {result.get('msg', '未知错误')}")
                    return False, 0
            else:
                print(f"❌ 任务完成提交请求失败 ({self.get_phone_tail()}): HTTP {response.status_code}")
                return False, 0

        except Exception as e:
            print(f"❌ 浏览任务异常 ({self.get_phone_tail()}): {str(e)}")
            return False, 0

    def get_task_name_by_id(self, task_id: str) -> str:
        try:
            member_info = self.get_member_info()
            if member_info:
                task_list = member_info.get("taskChannel", {}).get("taskList", [])
                for task in task_list:
                    if str(task.get("id")) == str(task_id):
                        return task.get("taskName", f"任务{task_id}")
            return f"任务{task_id}"
        except Exception:
            return f"任务{task_id}"

    def run_all_possible_tasks(self) -> int:
        print(f"\n🎯 开始执行指定浏览任务 ({self.get_phone_tail()})")
        all_task_ids = list(range(1, 15))  # 若需限制任务,可改为 [10,11,12,14]
        total_gold = 0
        success_count = 0

        for task_id in all_task_ids:
            task_name = self.get_task_name_by_id(str(task_id))
            print(f"🔄 尝试执行{task_name} (ID:{task_id}) ({self.get_phone_tail()})...")

            success, gold = self.complete_browse_task_original(str(task_id), task_name)
            if success:
                success_count += 1
                total_gold += gold
                print(f"✅ {task_name} 完成,获得 {gold} 金币")
            else:
                print(f"❌ {task_name} 执行失败或已完成")

            time.sleep(random.uniform(2, 4))

        print(f"📊 指定任务完成统计 ({self.get_phone_tail()}): {success_count}/{len(all_task_ids)},获得 {total_gold} 金币")
        return total_gold

    def run_lottery_task(self) -> Tuple[str, str]:
        if not self.lottery_module:
            self.lottery_module = JiuxianLotteryModule(self.session, self.token, self.username)
        lottery_success, lottery_prize = self.lottery_module.lottery_draw()
        return ('完成' if lottery_success else '失败'), lottery_prize

    def run_seventh_day_lottery(self) -> str:
        if self.continuous_sign_days >= 7:
            print(f"\n🎉 连续签到{self.continuous_sign_days}天,执行额外抽奖 ({self.get_phone_tail()})")
            if self.lottery_module:
                _, lottery_prize = self.lottery_module.lottery_draw()
                return lottery_prize
        return ""

    def run_all_tasks(self) -> Dict:
        phone_tail = self.get_phone_tail()
        print(f"\n🚀 开始执行所有任务 ({phone_tail})")

        results = {
            'phone_tail': phone_tail,
            'nickname': self.nickname,
            'login_success': False,
            'sign_success': False,
            'sign_gold': 0,
            'continuous_days': 0,
            'total_gold': 0,
            'today_gold': 0,
            'lottery_status': '未执行',
            'lottery_prize': '',
            'all_possible_tasks_gold': 0
        }

        # 1. 登录
        print(f"🔐 登录账号 ({phone_tail})...")
        if not self.smart_login():
            print(f"❌ 登录失败 ({phone_tail})")
            return results
        results['login_success'] = True
        results['nickname'] = self.nickname

        # 2. 获取会员信息
        member_info = self.get_member_info()
        if member_info:
            results['total_gold'] = self.total_gold
            results['continuous_days'] = self.continuous_sign_days
            print(f"💰 当前总金币: {results['total_gold']}")
            print(f"📅 连续签到天数: {results['continuous_days']}")

        # 3. 签到
        if not self.is_signed_today:
            print(f"📝 执行签到 ({phone_tail})...")
            sign_success, sign_gold = self.user_sign()
            results['sign_success'] = sign_success
            results['sign_gold'] = sign_gold
            results['today_gold'] += sign_gold
            results['continuous_days'] = self.continuous_sign_days
        else:
            print(f"✅ 今日已签到过 ({phone_tail})")
            results['sign_success'] = True
            results['sign_gold'] = 0
            results['continuous_days'] = self.continuous_sign_days

        # 4. 浏览任务
        print(f"🎯 执行所有可能浏览任务 ({phone_tail})...")
        all_tasks_gold = self.run_all_possible_tasks()
        results['today_gold'] += all_tasks_gold
        results['all_possible_tasks_gold'] = all_tasks_gold

        # 5. 抽奖任务
        print(f"🎰 运行抽奖任务 ({phone_tail})...")
        lottery_status, lottery_prize = self.run_lottery_task()
        results['lottery_status'] = lottery_status
        results['lottery_prize'] = lottery_prize

        # 6. 连续签到额外抽奖
        seventh_lottery_prize = self.run_seventh_day_lottery()
        if seventh_lottery_prize and seventh_lottery_prize != "已抽过":
            if results['lottery_prize'] and results['lottery_prize'] != "未执行":
                results['lottery_prize'] = f"{results['lottery_prize']}, {seventh_lottery_prize}"
            else:
                results['lottery_prize'] = seventh_lottery_prize

        # 7. 更新信息
        updated_member_info = self.get_member_info()
        if updated_member_info:
            results['total_gold'] = self.total_gold
            results['continuous_days'] = self.continuous_sign_days

        # 打印最终结果
        print(f"\n📊 任务执行完成 ({phone_tail})")
        print(f"✅ 签到: {'成功' if results['sign_success'] else '失败'}")
        print(f"💰 签到金币: {results['sign_gold']}")
        print(f"📅 连续签到: {results['continuous_days']} 天")
        print(f"🎯 浏览任务金币: {results['all_possible_tasks_gold']}")
        print(f"🎰 抽奖: {results['lottery_status']} - {results['lottery_prize']}")
        print(f"💰 今日获得: {results['today_gold']} 金币")
        print(f"💰 当前总金币: {results['total_gold']}")

        return results

# 批量运行管理器
class JiuxianBatchRunner:
    def __init__(self):
        self.results = []
        self.total_accounts = 0
        self.success_accounts = 0

    def parse_accounts_from_env(self) -> List[Tuple[str, str]]:
        accounts = []
        jiuxian_env = os.getenv('jiuxian')
        if jiuxian_env:
            print(f"📝 从环境变量读取账号配置")
            for line in jiuxian_env.strip().split('\n'):
                line = line.strip()
                if line and '#' in line:
                    username, password = line.split('#', 1)
                    username, password = username.strip(), password.strip()
                    if username and password:
                        accounts.append((username, password))
                        print(f"📱 账号: {username[:3]}****{username[-4:]}")
        return accounts

    def generate_report_content(self) -> str:
        total_today_gold = sum(result.get('today_gold', 0) for result in self.results)
        total_current_gold = sum(result.get('total_gold', 0) for result in self.results)
        success_count = sum(1 for result in self.results if result.get('login_success'))

        content = f"🍷 酒仙网任务执行报告\n\n"
        content += f"📱 总账号数: {self.total_accounts}\n"
        content += f"✅ 成功账号: {success_count}\n"
        content += f"❌ 失败账号: {self.total_accounts - success_count}\n"
        content += f"💰 今日总获得金币: {total_today_gold}\n"
        content += f"💰 当前总金币: {total_current_gold}\n\n"

        content += f"📋 详细结果:\n"
        for result in self.results:
            if result.get('login_success'):
                content += f"  📱 {result.get('nickname', '未知用户')} ({result.get('phone_tail', '未知')}): "
                content += f"签到{result.get('sign_gold', 0)}金, "
                content += f"任务{result.get('all_possible_tasks_gold', 0)}金, "
                content += f"今日{result.get('today_gold', 0)}金, "
                content += f"总{result.get('total_gold', 0)}金, "
                content += f"连续{result.get('continuous_days', 0)}天, "
                content += f"抽奖:{result.get('lottery_prize', '未知')}\n"

        exec_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
        content += f"\n🕐 执行时间: {exec_time}"
        return content

    def run_batch(self):
        print("🚀 开始批量运行酒仙签到脚本")
        print("=" * 50)

        accounts = self.parse_accounts_from_env()
        self.total_accounts = len(accounts)

        if self.total_accounts == 0:
            print("❌ 未找到有效的账号配置")
            return

        print(f"📊 共找到 {self.total_accounts} 个账号")

        for i, (username, password) in enumerate(accounts, 1):
            print(f"\n{'='*30}")
            print(f"👤 处理第 {i}/{self.total_accounts} 个账号: {username[:3]}****{username[-4:]}")
            print(f"{'='*30}")

            try:
                jiuxian = Jiuxian(username, password)
                result = jiuxian.run_all_tasks()
                self.results.append(result)
                if result['login_success']:
                    self.success_accounts += 1

                if i < self.total_accounts:
                    delay = random.uniform(5, 10)
                    print(f"⏳ 随机延迟 {delay:.1f} 秒后处理下一个账号...")
                    time.sleep(delay)

            except Exception as e:
                print(f"❌ 处理账号 {username[:3]}****{username[-4:]} 时发生异常: {str(e)}")

        self.print_summary()

        report_content = self.generate_report_content()
        title = f"🍷 酒仙网任务报告 - {self.success_accounts}/{self.total_accounts}成功"
        QLNotifier.send(title, report_content)

    def print_summary(self):
        print(f"\n{'='*50}")
        print("📊 批量执行汇总")
        print(f"{'='*50}")
        print(f"📱 总账号数: {self.total_accounts}")
        print(f"✅ 成功账号: {self.success_accounts}")
        print(f"❌ 失败账号: {self.total_accounts - self.success_accounts}")

        if self.success_accounts > 0:
            total_today_gold = sum(result.get('today_gold', 0) for result in self.results)
            total_current_gold = sum(result.get('total_gold', 0) for result in self.results)
            print(f"💰 今日总获得金币: {total_today_gold}")
            print(f"💰 当前总金币: {total_current_gold}")

            print(f"\n📋 详细结果:")
            for result in self.results:
                if result.get('login_success'):
                    print(f"  📱 {result.get('nickname', '未知用户')} ({result.get('phone_tail', '未知')}): "
                          f"签到{result.get('sign_gold', 0)}金, "
                          f"任务{result.get('all_possible_tasks_gold', 0)}金, "
                          f"今日{result.get('today_gold', 0)}金, "
                          f"总{result.get('total_gold', 0)}金, "
                          f"连续{result.get('continuous_days', 0)}天, "
                          f"抽奖:{result.get('lottery_prize', '未知')}")

# 主函数
def main():
    print("🍷 酒仙网签到脚本 - 抽奖修复版")
    print("=" * 50)
    runner = JiuxianBatchRunner()
    runner.run_batch()

if __name__ == "__main__":
    main()
温馨提示: 本文最后更新于2025-11-14 12:37:47,某些文章具有时效性,若有错误或已失效,请在下方 留言或联系 哗哗资源分享
© 版权声明
THE END
喜欢就支持一下吧
点赞19赞赏 分享