diff --git a/WX_Applet/Applet_JYHS_DDYX.py b/WX_Applet/Applet_JYHS_DDYX.py index b92c74d..e78fceb 100644 --- a/WX_Applet/Applet_JYHS_DDYX.py +++ b/WX_Applet/Applet_JYHS_DDYX.py @@ -1,530 +1,469 @@ # cron: 2 7 * * * # new Env("旧衣回收_铛铛一下") -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -铛铛一下 - 养鸡场版(自动获取账号 + 自动提现 + 推送通知) -直接从养鸡场获取微信账号列表,无需手动配置wxid -""" - -import os -import sys -import time +import hashlib import random +import time import requests +import os +import logging +import traceback +import base64 import json +from Crypto.Cipher import AES +from Crypto.Random import get_random_bytes from datetime import datetime -print("=" * 50) -print("脚本开始加载...") -print("=" * 50) +# ====================== 养鸡场配置 ====================== +WX_TOKEN = os.getenv('wx_token') # 养鸡场 Authorization 令牌 +wx_cloud = os.getenv('wx_cloud', 'http://192.168.31.203:666') # 养鸡场服务地址 +# ======================================================== -# ==================== 配置 ==================== -CHICKEN_FARM_URL = os.getenv("wx_cloud", "http://127.0.0.1:666") -CHICKEN_FARM_TOKEN = os.getenv("wx_token", "") -WX_APPID = "wxe378d2d7636c180e" # 铛铛一下的appid -REMOVE_WXIDS = os.getenv("REMOVE_WXIDS", "") # 需要剔除的wxid,逗号分隔 -DEFAULT_WITHDRAW_BALANCE = float(os.getenv("WITHDRAW_BALANCE", "0.3")) # 默认超过0.3元提现 -NOTIFY = os.getenv("LY_NOTIFY", "false").lower() == "true" # 是否推送通知 +remove_wxids1 = ["wxid_11111111111111"] # 需要剔除的多个wxid +DEFAULT_WITHDRAW_BALANCE = 0.3 # 默认超过该金额进行提现,需大于等于0.3 +MULTI_ACCOUNT_SPLIT = ["\n", "@"] # 分隔符列表 +MULTI_ACCOUNT_PROXY = False # 是否使用多账号代理,默认不使用,True则使用多账号代理 -print(f"养鸡场地址: {CHICKEN_FARM_URL}") -print(f"Token状态: {'已配置' if CHICKEN_FARM_TOKEN else '未配置'}") -print(f"提现阈值: {DEFAULT_WITHDRAW_BALANCE}元") -print(f"通知推送: {'开启' if NOTIFY else '关闭'}") -print(f"AppID: {WX_APPID}") +# 微信小程序ID(根据实际业务调整) +WX_APPID = "wxe378d2d7636c180e" -# ==================== 通知模块 ==================== -def send_notify(title, content): - """发送通知""" - if not NOTIFY: - return - - try: - # 尝试导入notify模块 - notify_path = "/ql/scripts/notify.py" - if os.path.exists(notify_path): - sys.path.insert(0, "/ql/scripts") - import notify - notify.send(title, content) - print("[通知] 已发送") - else: - # 尝试下载notify模块 - print("[通知] notify.py不存在,尝试下载...") - url = "https://raw.githubusercontent.com/whyour/qinglong/refs/heads/develop/sample/notify.py" - resp = requests.get(url, timeout=10) - with open(notify_path, "w", encoding="utf-8") as f: - f.write(resp.text) - import notify - notify.send(title, content) - print("[通知] 已发送") - except Exception as e: - print(f"[通知] 发送失败: {e}") - -# ==================== 从养鸡场获取账号列表 ==================== -def get_accounts_from_farm(): - """从养鸡场获取微信账号列表""" - print("[获取账号] 开始从养鸡场获取账号列表...") - - if not CHICKEN_FARM_TOKEN: - print("[获取账号] 错误: 未设置wx_token") - return [] - - url = f"{CHICKEN_FARM_URL}/prod-api/wechat/wechat/list" - headers = { - "Authorization": CHICKEN_FARM_TOKEN, - "Content-Type": "application/json" - } - params = {"pageNum": 1, "pageSize": 1000} - - try: - print(f"[获取账号] 请求URL: {url}") - resp = requests.get(url, headers=headers, params=params, timeout=10) - print(f"[获取账号] 响应状态: {resp.status_code}") - result = resp.json() - - if result.get("code") == 200: - accounts = result.get("rows", []) - print(f"[获取账号] 成功,共获取 {len(accounts)} 个账号") - - # 剔除指定wxid - if REMOVE_WXIDS: - remove_list = [wxid.strip() for wxid in REMOVE_WXIDS.split(",") if wxid.strip()] - accounts = [a for a in accounts if a.get("wxId") not in remove_list] - print(f"[获取账号] 剔除后剩余 {len(accounts)} 个账号") - - return accounts - else: - print(f"[获取账号] 失败: {result.get('msg')}") - return [] - except Exception as e: - print(f"[获取账号] 异常: {e}") - return [] - -# ==================== 从养鸡场获取CODE ==================== -def get_code_from_farm(wxid: str): - """从养鸡场获取code""" - print(f"[获取code] 请求: {wxid}") - - if not CHICKEN_FARM_TOKEN: - print("[获取code] 错误: 未设置wx_token") - return None - - url = f"{CHICKEN_FARM_URL}/prod-api/wechat/api/getMiniProgramCode" - headers = { - "Authorization": CHICKEN_FARM_TOKEN, - "Content-Type": "application/json" - } - data = {"wxid": wxid, "appid": WX_APPID} - - try: - resp = requests.post(url, json=data, headers=headers, timeout=10) - result = resp.json() - - if result.get("code") == 200 and result.get("data"): - code = result["data"] - if isinstance(code, dict): - code = code.get("code") - print(f"[获取code] 成功: {code[:10]}...") - return code - else: - print(f"[获取code] 失败: {result.get('msg')}") - return None - except Exception as e: - print(f"[获取code] 异常: {e}") - return None - -# ==================== 铛铛一下业务接口 ==================== -def wxlogin(session, code): - """微信登录""" - try: - url = "https://vues.dd1x.cn/wechat/login" - params = {"code": code, "channelId": 154} - resp = session.get(url, params=params, timeout=10) - result = resp.json() - - if result.get('code') == 0: - token = result['data']['token'] - session.headers["Token"] = token - tel = result['data'].get('tel', '未知') - if len(tel) > 7: - tel = tel[:3] + "****" + tel[-4:] - print(f"[登录] 成功: {tel}") - return True, tel - else: - print(f"[登录] 失败: {result.get('msg')}") - return False, None - except Exception as e: - print(f"[登录] 异常: {e}") - return False, None - -def sign_in(session): - """签到""" - try: - url = "https://vues.dd1x.cn/api/v2/sign_join" - resp = session.get(url, timeout=10) - result = resp.json() - if result.get('code') == 0: - print(f"[签到] 成功") - return True - else: - print(f"[签到] 失败: {result.get('msg')}") - return False - except Exception as e: - print(f"[签到] 异常: {e}") - return False - -def lottery(session): - """抽奖""" - try: - url = "https://vues.dd1x.cn/front/activity/update_lottery_result" - params = {"id": 3438615} - resp = session.get(url, params=params, timeout=10) - result = resp.json() - if result.get('code') == 0: - good_name = result['data']['goodName'] - print(f"[抽奖] 获得: {good_name}") - return True, good_name - else: - print(f"[抽奖] 失败: {result.get('msg')}") - return False, None - except Exception as e: - print(f"[抽奖] 异常: {e}") - return False, None - -def add_lottery_count(session): - """增加抽奖次数""" - try: - url = "https://vues.dd1x.cn/front/activity/add_lottery_count" - resp = session.get(url, timeout=10) - result = resp.json() - if result.get('code') == 0: - print(f"[增加次数] 成功") - return True - elif "达到上限" in result.get('msg', ''): - print(f"[增加次数] 已达上限") - return False - else: - print(f"[增加次数] 失败: {result.get('msg')}") - return False - except: - return False - -def get_withdrawal_info(session): - """获取提现相关信息(余额和可提现列表)""" - try: - url = "https://vues.dd1x.cn/api/h/get_withdrawal_trade_list" - resp = session.get(url, timeout=10) - result = resp.json() - if result.get('code') == 0 and result.get('data'): - data_list = result['data'] - if data_list: - balance = data_list[0].get('money', 0) - print(f"[余额] {balance}元") - return balance, data_list - except Exception as e: - print(f"[余额] 获取失败: {e}") - return 0, None - -def withdraw(session, total_money, withdrawal_list): - """执行提现""" - try: - url = "https://vues.dd1x.cn/api/h/withdrawal" - payload = { - "totalMoney": total_money, - "type": 1, - "withdrawalDetailPojoList": withdrawal_list - } - resp = session.post(url, json=payload, timeout=10) - result = resp.json() - if result.get('code') == 0: - print(f"[提现] 成功!提现 {total_money} 元") - return True, result.get('msg', '提现成功') - else: - print(f"[提现] 失败: {result.get('msg')}") - return False, result.get('msg') - except Exception as e: - print(f"[提现] 异常: {e}") - return False, str(e) - -# ==================== 抽奖循环 ==================== -def do_lottery_loop(session, max_rounds=3): +class WXBizDataCryptUtil: """ - 执行抽奖循环 - 返回中奖记录列表 + 微信小程序加解密工具 """ - prizes = [] - - # 先抽3次 - for i in range(3): - success, prize = lottery(session) - if success and prize: - prizes.append(prize) - time.sleep(random.randint(2, 4)) - - # 增加抽奖次数并继续抽 - for i in range(max_rounds): - if not add_lottery_count(session): - break - time.sleep(random.randint(1, 2)) - success, prize = lottery(session) - if success and prize: - prizes.append(prize) - time.sleep(random.randint(2, 4)) - - return prizes + def __init__(self, sessionKey): + self.sessionKey = sessionKey -# ==================== 单个账号执行 ==================== -def run_account(account, idx, total, results): - """执行单个账号的任务""" - wxid = account.get("wxId") - name = account.get("wxName", wxid) - - print(f"\n{'='*40}") - print(f"账号 {idx}/{total}: {name} ({wxid})") - print(f"{'='*40}") - - # 记录结果 - account_result = { - "index": idx, - "name": name, - "wxid": wxid, - "success": False, - "phone": "", - "sign_success": False, - "lottery_count": 0, - "prizes": [], - "balance": 0, - "withdrawn": False, - "withdraw_amount": 0, - "error_msg": "" - } - - # 1. 获取code - code = get_code_from_farm(wxid) - if not code: - print(f"❌ 获取code失败,跳过账号") - account_result["error_msg"] = "获取code失败" - results.append(account_result) - return - - # 2. 创建session - session = requests.Session() - session.headers["User-Agent"] = "Mozilla/5.0 (Linux; Android 12) AppleWebKit/537.36" - - # 3. 登录 - login_success, phone = wxlogin(session, code) - if not login_success: - account_result["error_msg"] = "登录失败" - results.append(account_result) - return - - account_result["phone"] = phone - time.sleep(random.randint(1, 3)) - - # 4. 签到 - sign_success = sign_in(session) - account_result["sign_success"] = sign_success - time.sleep(random.randint(1, 3)) - - # 5. 抽奖 - prizes = do_lottery_loop(session, max_rounds=3) - if prizes: - account_result["prizes"] = prizes - account_result["lottery_count"] = len(prizes) - print(f"[中奖记录] {', '.join(prizes)}") - - # 6. 获取余额并判断是否提现 - balance, withdrawal_list = get_withdrawal_info(session) - account_result["balance"] = balance - - if balance >= DEFAULT_WITHDRAW_BALANCE and withdrawal_list: - print(f"[提现判断] 余额 {balance}元 >= {DEFAULT_WITHDRAW_BALANCE}元,开始提现...") - withdraw_success, withdraw_msg = withdraw(session, balance, withdrawal_list) - account_result["withdrawn"] = withdraw_success - account_result["withdraw_amount"] = balance if withdraw_success else 0 - account_result["withdraw_msg"] = withdraw_msg - else: - print(f"[提现判断] 余额 {balance}元 < {DEFAULT_WITHDRAW_BALANCE}元,暂不提现") - - account_result["success"] = True - results.append(account_result) - print(f"\n✅ 账号 {idx} 执行完成") - -# ==================== 生成通知内容 ==================== -def build_notify_content(results): - """生成详细的通知内容""" - total = len(results) - success = sum(1 for r in results if r.get("success")) - fail = total - success - - total_withdrawn = sum(1 for r in results if r.get("withdrawn")) - total_withdraw_amount = sum(r.get("withdraw_amount", 0) for r in results) - total_balance = sum(r.get("balance", 0) for r in results) - - # 统计中奖 - all_prizes = [] - prize_count = {} - for r in results: - for prize in r.get("prizes", []): - all_prizes.append(prize) - prize_count[prize] = prize_count.get(prize, 0) + 1 - - # 计算成功率 - success_rate = (success / total * 100) if total > 0 else 0 - - # 构建通知内容 - now = datetime.now().strftime("%Y-%m-%d %H:%M:%S") - - content = f""" -╔══════════════════════════════════════════════════════════╗ -║ 铛铛一下 执行报告 ║ -║ {now} ║ -╚══════════════════════════════════════════════════════════╝ - -📊 整体统计 -────────────────────────────────────────────────────────── -总账号数 : {total} -成功账号 : {success} -失败账号 : {fail} -成功率 : {success_rate:.1f}% - -💰 收益统计 -────────────────────────────────────────────────────────── -当前总余额 : {total_balance:.2f} 元 -本次提现总额 : {total_withdraw_amount:.2f} 元 -提现账号数 : {total_withdrawn} - -🎁 中奖统计 -────────────────────────────────────────────────────────── -总中奖次数 : {len(all_prizes)} -""" - - if prize_count: - content += "\n奖品明细:\n" - for prize, count in prize_count.items(): - content += f" • {prize}: {count}次\n" - - content += """ -📋 账号详情 -────────────────────────────────────────────────────────── -""" - - for r in results: - status = "✅" if r.get("success") else "❌" - content += f"\n{status} 【账号{r['index']}】{r['name']}\n" - if r.get("phone"): - content += f" 手机号: {r['phone']}\n" - if r.get("sign_success"): - content += f" 签到: 成功\n" + def encrypt(self, data, iv=None): + """ + data: dict或str,若为dict自动转为json字符串 + iv: base64字符串,若为None自动生成 + 返回: (加密数据base64, iv base64) + """ + if isinstance(data, dict): + data = json.dumps(data, separators=(',', ':')) + if iv is None: + iv_bytes = get_random_bytes(16) + iv = base64.b64encode(iv_bytes).decode('utf-8') else: - content += f" 签到: 失败\n" - if r.get("prizes"): - content += f" 中奖: {', '.join(r['prizes'])}\n" - else: - content += f" 中奖: 无\n" - content += f" 余额: {r.get('balance', 0):.2f}元\n" - if r.get("withdrawn"): - content += f" 提现: ✅ 成功 {r.get('withdraw_amount', 0):.2f}元\n" - elif r.get("balance", 0) >= DEFAULT_WITHDRAW_BALANCE: - content += f" 提现: ❌ 失败 ({r.get('withdraw_msg', '未知错误')})\n" - else: - content += f" 提现: 未达到阈值({DEFAULT_WITHDRAW_BALANCE}元)\n" - if r.get("error_msg"): - content += f" 错误: {r['error_msg']}\n" - - content += """ -══════════════════════════════════════════════════════════ -""" - - return content + iv_bytes = base64.b64decode(iv) + sessionKey = base64.b64decode(self.sessionKey) + cipher = AES.new(sessionKey, AES.MODE_CBC, iv_bytes) + padded = self._pad(data.encode('utf-8')) + encrypted = cipher.encrypt(padded) + encrypted_b64 = base64.b64encode(encrypted).decode('utf-8') + return encrypted_b64, iv -# ==================== 打印控制台汇总 ==================== -def print_summary(results): - """在控制台打印汇总""" - print("\n" + "=" * 60) - print(" 执行汇总") - print("=" * 60) - - total = len(results) - success = sum(1 for r in results if r.get("success")) - total_balance = sum(r.get("balance", 0) for r in results) - total_withdraw = sum(r.get("withdraw_amount", 0) for r in results) - - print(f"\n📊 统计信息:") - print(f" 总账号: {total}") - print(f" 成功: {success}") - print(f" 失败: {total - success}") - print(f" 总余额: {total_balance:.2f}元") - print(f" 本次提现: {total_withdraw:.2f}元") - - print(f"\n📋 账号详情:") - print("-" * 60) - for r in results: - status = "✅" if r.get("success") else "❌" - prizes_str = ", ".join(r.get("prizes", [])) if r.get("prizes") else "无" - print(f"{status} {r['name']}: {r.get('balance', 0):.2f}元 | 中奖: {prizes_str}") - - print("\n" + "=" * 60) - -# ==================== 主程序 ==================== -def run(): - print("=" * 50) - print("铛铛一下 - 养鸡场版(自动获取账号 + 自动提现 + 推送通知)") - print(f"时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") - print("=" * 50) - - # 检查环境变量 - if not CHICKEN_FARM_TOKEN: - print("❌ 请设置环境变量 wx_token") - if NOTIFY: - send_notify("铛铛一下 - 执行失败", "未设置 wx_token 环境变量") - return - - # 从养鸡场获取账号列表 - accounts = get_accounts_from_farm() - if not accounts: - print("❌ 未获取到任何微信账号") - if NOTIFY: - send_notify("铛铛一下 - 执行失败", "未获取到任何微信账号") - return - - print(f"\n共 {len(accounts)} 个账号\n") - - # 存储结果 - results = [] - - # 遍历执行每个账号 - for idx, account in enumerate(accounts, 1): + def decrypt(self, encryptedData, iv): + """ + encryptedData: base64字符串 + iv: base64字符串 + 返回: dict或str + """ + sessionKey = base64.b64decode(self.sessionKey) + encryptedData = base64.b64decode(encryptedData) + iv = base64.b64decode(iv) + cipher = AES.new(sessionKey, AES.MODE_CBC, iv) + decrypted = self._unpad(cipher.decrypt(encryptedData)) try: - run_account(account, idx, len(accounts), results) - # 账号间延迟 - if idx < len(accounts): - delay = random.randint(3, 8) - print(f"\n⏳ 等待 {delay} 秒后执行下一个账号...") - time.sleep(delay) - except Exception as e: - print(f"❌ 账号执行异常: {e}") - results.append({ - "index": idx, - "name": account.get("wxName", account.get("wxId")), - "success": False, - "error_msg": str(e) - }) - continue - - # 打印控制台汇总 - print_summary(results) - - # 发送通知 - if NOTIFY: - success_count = sum(1 for r in results if r.get("success")) - total_balance = sum(r.get("balance", 0) for r in results) - title = f"铛铛一下 - 执行完成 (成功{success_count}/{len(results)})" - content = build_notify_content(results) - send_notify(title, content) - - print("\n所有任务执行完成") + return json.loads(decrypted) + except Exception: + return decrypted.decode('utf-8') + + def _pad(self, s): + pad_len = 16 - len(s) % 16 + return s + bytes([pad_len] * pad_len) + + def _unpad(self, s): + return s[:-s[-1]] + +class AutoTask: + def __init__(self, site_name): + """ + 初始化自动任务类 + :param site_name: 站点名称,用于日志显示 + """ + self.site_name = site_name + self.proxy_url = os.getenv("PROXY_API_URL") # 代理api,返回一条txt文本,内容为代理ip:端口 + self.wx_appid = WX_APPID # 微信小程序id + self.host = "vues.dd1x.cn" + self.user_agent = "Mozilla/5.0 (Linux; Android 12; M2012K11AC Build/SKQ1.220303.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/134.0.6998.136 Mobile Safari/537.36 XWEB/1340129 MMWEBSDK/20240301 MMWEBID/9871 MicroMessenger/8.0.48.2580(0x28003036) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android" + self.setup_logging() + + def setup_logging(self): + """ + 配置日志系统 + """ + logging.basicConfig( + level=logging.INFO, + format='%(asctime)s - %(levelname)s\t- %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + handlers=[ + logging.StreamHandler() + ] + ) + + def get_proxy(self): + """ + 获取代理 + :return: 代理 + """ + if not self.proxy_url: + logging.warning("[获取代理]没有找到环境变量PROXY_API_URL,不使用代理") + return None + url = self.proxy_url + response = requests.get(url) + proxy = response.text.strip() # 去除首尾空格和换行 + logging.info(f"[获取代理]: {proxy}") + return proxy + + def check_proxy(self, proxy, session): + """ + 检查代理 + :param proxy: 代理 + :param session: session + :return: 是否可用 + """ + try: + url = f"http://{self.host}/api/v2/get_sign_list" + session.headers["Token"] = "" + response = session.get(url, timeout=5) + if response.status_code == 200: + logging.info(f"[检查代理]: {proxy} 应该可用") + return True + else: + logging.info(f"[检查代理]: {response.text}") + return False + except Exception as e: + logging.error(f"[检查代理]代理 {proxy} 不可用: {str(e)}") + return False + + def get_wechat_account_list(self): + """ + 从养鸡场接口获取账号列表 + :return: 账号列表/False + """ + try: + if not WX_TOKEN: + logging.error("[获取账号列表]未设置环境变量 wx_token") + return False + + url = f"{wx_cloud}/prod-api/wechat/wechat/list?pageNum=1&pageSize=1000" + headers = { + 'Authorization': WX_TOKEN, + 'Content-Type': 'application/json', + } + + response = requests.get(url, headers=headers, timeout=10) + response.raise_for_status() + res_data = response.json() + + if res_data and res_data.get('code') == 200 and isinstance(res_data.get('rows'), list): + accounts = res_data['rows'] + logging.info(f"[获取账号列表]成功获取到 {len(accounts)} 个账号") + return accounts + else: + logging.error(f"[获取账号列表]接口返回异常: {json.dumps(res_data)}") + return False + except Exception as e: + logging.error(f"[获取账号列表]发生错误: {str(e)}\n{traceback.format_exc()}") + return False + + def get_wx_code_yjc(self, wxid): + """ + 使用养鸡场接口获取微信小程序Code + :param wxid: 微信ID + :return: code/False + """ + try: + if not WX_TOKEN: + logging.error("[获取Code]未设置环境变量 wx_token") + return False + + url = f"{wx_cloud}/prod-api/wechat/api/getMiniProgramCode" + headers = { + 'Authorization': WX_TOKEN, + 'Content-Type': 'application/json' + } + payload = { + "wxid": wxid, + "appid": self.wx_appid + } + + response = requests.post(url, json=payload, headers=headers, timeout=10) + response.raise_for_status() + res_data = response.json() + + if res_data and res_data.get('code') == 200 and res_data.get('data', {}).get('code'): + code = res_data['data']['code'] + logging.info(f"[获取Code]成功获取 wxid:{wxid} 的code") + return code + else: + logging.error(f"[获取Code]接口返回异常: {json.dumps(res_data)}") + return False + except Exception as e: + logging.error(f"[获取Code]wxid:{wxid} 发生错误: {str(e)}\n{traceback.format_exc()}") + return False + + def wxlogin(self, session, code): + """ + 登录 + :param session: session + :param code: 微信code + :return: 登录结果 + """ + try: + url = f"https://{self.host}/wechat/login" + params = { + "code": code, + "channelId": 154 + } + response = session.get(url, params=params, timeout=10) + response.raise_for_status() + response_json = response.json() + + if response_json.get('code') == 0: + tel = response_json['data'].get('tel', '') + # 号码中间4位*号代替 + if tel: + tel = tel[:3] + "****" + tel[-4:] + logging.info(f"[登录]成功: 当前账号 {tel}") + token = response_json['data']['token'] + session.headers["Token"] = token + return True + else: + logging.error(f"[登录]发生错误: {response_json.get('msg', '未知错误')}") + return False + except requests.RequestException as e: + logging.error(f"[登录]发生网络错误: {str(e)}\n{traceback.format_exc()}") + return False + except Exception as e: + logging.error(f"[登录]发生错误: {str(e)}\n{traceback.format_exc()}") + return False + + def sign_in(self, session): + """ + 签到 + :param session: session + :return: 签到结果 + """ + try: + url = f"https://{self.host}/api/v2/sign_join" + response = session.get(url, timeout=10) + response.raise_for_status() + response_json = response.json() + + if response_json.get('code') == 0: + logging.info(f"[签到]: 成功") + return True + else: + logging.warning(f"[签到]: {response_json.get('msg', '未知错误')}") + return False + except Exception as e: + logging.error(f"[签到]发生错误: {str(e)}\n{traceback.format_exc()}") + return False + + def add_lottery_count(self, session): + """ + 增加抽奖次数 + :param session: session + :return: 增加抽奖次数结果 + """ + try: + url = f"https://{self.host}/front/activity/add_lottery_count" + response = session.get(url, timeout=10) + response.raise_for_status() + response_json = response.json() + + if response_json.get('code') == 0: + logging.info(f"[增加抽奖次数]: 成功") + return True + elif "达到上限" in response_json.get('msg', ''): + logging.warning(f"[增加抽奖次数]: {response_json.get('msg')}") + return False + else: + logging.error(f"[增加抽奖次数]发生错误: {response_json.get('msg', '未知错误')}") + return False + except Exception as e: + logging.error(f"[增加抽奖次数]发生错误: {str(e)}\n{traceback.format_exc()}") + return False + + def update_lottery_result(self, session): + """ + 更新抽奖结果(执行抽奖) + :param session: session + :return: 抽奖结果 + """ + try: + url = f"https://{self.host}/front/activity/update_lottery_result" + params = { + "id": 3438615 + } + response = session.get(url, params=params, timeout=10) + response.raise_for_status() + response_json = response.json() + + if response_json.get('code') == 0: + good_name = response_json['data'].get('goodName', '未知奖励') + logging.info(f"[抽奖]: 获得{good_name}") + return True + else: + logging.warning(f"[抽奖]: {response_json.get('msg', '未知错误')}") + return False + except Exception as e: + logging.error(f"[抽奖]发生错误: {str(e)}\n{traceback.format_exc()}") + return False + + def get_withdrawal_trade_list(self, session): + """ + 获取提现相关数据 + :param session: session + :return: (余额, 提现数据)/False + """ + try: + url = f"https://{self.host}/api/h/get_withdrawal_trade_list" + response = session.get(url, timeout=10) + response.raise_for_status() + response_json = response.json() + + if response_json.get('code') == 0 and isinstance(response_json.get('data'), list) and len(response_json['data']) > 0: + balance = float(response_json['data'][0].get('money', 0)) + logging.info(f"[余额]: {balance}元") + return balance, response_json['data'] + else: + logging.error(f"[获取提现相关数据]发生错误: {response_json.get('msg', '未知错误')}") + return False + except Exception as e: + logging.error(f"[获取提现相关数据]发生错误: {str(e)}\n{traceback.format_exc()}") + return False + + def withdraw(self, session, balance, withdrawal_trade_list): + """ + 提现 + :param session: session + :param balance: 余额 + :param withdrawal_trade_list: 提现相关数据 + :return: 提现结果 + """ + try: + url = f"https://{self.host}/api/h/withdrawal" + payload = { + "totalMoney": balance, + "type": 1, + "withdrawalDetailPojoList": withdrawal_trade_list + } + response = session.post(url, json=payload, timeout=10) + response.raise_for_status() + response_json = response.json() + + if response_json.get('code') == 0: + logging.info(f"[提现]: {response_json.get('msg', '提现成功')}") + return True + else: + logging.warning(f"[提现]: {response_json.get('msg', '提现失败')}") + return False + except Exception as e: + logging.error(f"[提现]发生错误: {str(e)}\n{traceback.format_exc()}") + return False + + def run(self): + """ + 运行任务 + """ + try: + logging.info(f"【{self.site_name}】开始执行任务") + + # 从养鸡场获取账号列表 + accounts = self.get_wechat_account_list() + if not accounts: + logging.error("【{self.site_name}】获取账号列表失败,任务终止") + return + + # 过滤需要剔除的账号 + combined_remove = set(remove_wxids1) + filtered_accounts = [acc for acc in accounts if acc.get('wxId') not in combined_remove] + logging.info(f"[账号过滤]剔除后剩余 {len(filtered_accounts)} 个账号") + + # 执行每个账号的任务 + for index, account in enumerate(filtered_accounts, 1): + wxid = account.get('wxId') + wxname = account.get('wxName', '未知昵称') + + logging.info("") + logging.info(f"------ 【账号{index}: {wxname} ({wxid})】开始执行任务 ------") + + # 初始化session和代理 + if MULTI_ACCOUNT_PROXY: + proxy = self.get_proxy() + session = requests.Session() + if proxy: + session.proxies.update({ + "http": f"http://{proxy}", + "https": f"http://{proxy}" + }) + # 检查代理,不可用则不使用代理 + if not self.check_proxy(proxy, session): + session.proxies.clear() + logging.warning("[代理]使用默认网络环境") + else: + session = requests.Session() + + session.headers["User-Agent"] = self.user_agent + + # 执行微信授权获取code + code = self.get_wx_code_yjc(wxid) + if code: + # 登录 + login_result = self.wxlogin(session, code) + time.sleep(random.randint(1, 3)) + + if login_result: + # 签到 + self.sign_in(session) + time.sleep(random.randint(1, 3)) + + # 抽奖循环 + lottery_result = self.update_lottery_result(session) + while lottery_result: + time.sleep(random.randint(3, 5)) + lottery_result = self.update_lottery_result(session) + + # 增加抽奖次数并继续抽奖 + add_count_result = self.add_lottery_count(session) + while add_count_result: + self.update_lottery_result(session) + time.sleep(random.randint(3, 5)) + add_count_result = self.add_lottery_count(session) + + # 提现逻辑 + withdraw_data = self.get_withdrawal_trade_list(session) + if withdraw_data: + balance, withdrawal_list = withdraw_data + if balance >= DEFAULT_WITHDRAW_BALANCE: + self.withdraw(session, balance, withdrawal_list) + time.sleep(random.randint(1, 3)) + else: + logging.warning(f"[提现]: 余额{balance}元不足{DEFAULT_WITHDRAW_BALANCE}元,不进行提现") + else: + logging.warning("[提现]: 获取提现数据失败") + else: + logging.error(f"[授权]wxid:{wxid} 获取Code失败,跳过该账号") + + logging.info(f"------ 【账号{index}: {wxname} ({wxid})】执行任务完成 ------") + # 账号间增加延迟,避免请求过快 + if index < len(filtered_accounts): + time.sleep(random.randint(2, 5)) + + except Exception as e: + logging.error(f"【{self.site_name}】执行过程中发生错误: {str(e)}\n{traceback.format_exc()}") + finally: + logging.info(f"【{self.site_name}】所有账号任务执行完毕") + -# ==================== 入口 ==================== if __name__ == "__main__": - run() \ No newline at end of file + # 检查必要环境变量 + if not WX_TOKEN: + print("错误:请先设置环境变量 wx_token") + exit(1) + + auto_task = AutoTask("铛铛一下") + auto_task.run() \ No newline at end of file