支持多账户
"""
new Env('ikuuu签到');
cron: 0 9 * * *
"""
import requests
import json
import re
import time
import base64
import urllib.parse
# ================= 配置区域 =================
# 在这里直接填写您的邮箱和密码(支持多账户)
ACCOUNTS = [
{"email": "[email protected]", "pwd": "passwd"},
]
# 域名配置
BASE_URL = "https://ikuuu.org"
# ===========================================
LOGIN_URL = f'{BASE_URL}/auth/login'
CHECKIN_URL = f'{BASE_URL}/user/checkin'
USER_URL = f'{BASE_URL}/user'
def get_headers():
return {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36',
'Referer': BASE_URL,
'Origin': BASE_URL,
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
}
def run_checkin():
log_content = ""
print(f"检测到 {len(ACCOUNTS)} 个账号,开始执行任务...\n")
for i, account in enumerate(ACCOUNTS):
email = account.get("email")
password = account.get("pwd")
print(f"=== 开始处理第 {i+1} 个账号: {email} ===")
session = requests.session()
headers = get_headers()
try:
# 1. 登录
login_data = {'email': email, 'passwd': password, 'code': ''}
login_resp = session.post(url=LOGIN_URL, headers=headers, data=login_data, timeout=10)
try:
login_json = login_resp.json()
except:
print("登录失败: 无法解析返回数据")
continue
if login_json.get('ret') != 1:
print(f"登录失败: {login_json.get('msg')}")
continue
print("登录成功,准备签到...")
# 2. 执行签到
checkin_resp = session.post(url=CHECKIN_URL, headers=headers, timeout=10)
try:
msg = checkin_resp.json().get('msg', '无返回消息')
except:
msg = "签到接口返回异常"
print(f"签到结果: {msg}")
# 3. 获取流量信息 (关键修改步骤)
user_page_resp = session.get(url=USER_URL, headers=headers, timeout=10)
raw_html = user_page_resp.text
# === 解码处理开始 ===
# 检测是否存在加密的 originBody
origin_body_match = re.search(r'var originBody = "(.*?)";', raw_html)
if origin_body_match:
try:
# 提取 Base64 字符串
b64_str = origin_body_match.group(1)
# 解码 Base64
decoded_bytes = base64.b64decode(b64_str)
# 解码 URL 编码 (对应网页JS中的 decodeURIComponent)
# 网页逻辑是: base64 -> split/map -> decodeURIComponent
# Python中直接由 base64 -> utf-8 字符串通常就够了,但为了保险处理特殊字符:
final_html = decoded_bytes.decode('utf-8', errors='ignore')
except Exception as e:
print(f"页面解密失败: {e}")
final_html = raw_html # 解密失败则尝试用原HTML
else:
final_html = raw_html
# === 解码处理结束 ===
# 4. 正则匹配流量
# 匹配逻辑:找到“剩余流量”这几个字,然后找它后面的第一个 counter
traffic_match = re.search(r'剩余流量.*?<span class="counter">(.*?)</span>', final_html, re.S)
if traffic_match:
traffic_info = traffic_match.group(1) + " GB"
else:
# 备用匹配:尝试直接匹配所有 counter,取第一个(通常是剩余流量)
backup_match = re.findall(r'<span class="counter">(.*?)</span>', final_html, re.S)
if backup_match:
traffic_info = backup_match[0] + " GB (可能不准)"
else:
traffic_info = "提取失败 (HTML结构变化)"
print(f"当前流量: {traffic_info}")
log_content += f"账号: {email}\n状态: {msg}\n剩余流量: {traffic_info}\n" + "-"*20 + "\n"
except Exception as e:
print(f"账号 {email} 发生异常: {str(e)}")
time.sleep(2)
print("\n")
return log_content
if __name__ == '__main__':
run_checkin()