diff --git a/iKuuu/README.md b/iKuuu/README.md
index 5c09e03..7767e88 100644
--- a/iKuuu/README.md
+++ b/iKuuu/README.md
@@ -40,6 +40,15 @@ task ik_signin 0 0 1 * * ?
## 更新日志
+### 2025-07-25
+- 智能域名发现机制。使用多种正则表达式模式从网页内容中提取域名,当域名不可用时,会从旧域名页面自动抓取新的可用域名,优先使用ikuuu相关域名,其次使用其他发现的域名
+- 增强的域名检测逻辑。能识别多种域名变更通知格式,从JavaScript跳转、登录链接等多个位置提取域名,过滤掉无效的域名格式
+- 完善的容错机制。当前域名 → 发现的新域名 → 备用域名列表,每个域名都会进行可达性测试,增加了超时、连接错误等异常处理
+- 改进的用户体验。每个步骤都有清晰的状态提示和图标,显示账户处理进度,提供详细的执行结果汇总
+- 新增功能。在通知中包含当前使用的域名,账户间延迟增加到2秒,避免请求过快,各种异常情况都有对应的错误信息
+
+---
+
### 2025-01-14
- 接口请求统一增加UA标识
diff --git a/iKuuu/ik_signin.py b/iKuuu/ik_signin.py
index d7c5fe5..6c63a0a 100644
--- a/iKuuu/ik_signin.py
+++ b/iKuuu/ik_signin.py
@@ -39,63 +39,229 @@ except ImportError:
send = lambda title, content: None # 创建空函数防止报错
# 初始域名
-ikun_host = "ikuuu.one" # 自动更新于2025-04-29 13:08:20
+ikun_host = "ikuuu.ch" # 自动更新于2025-04-29 13:08:20
backup_hosts = ["ikuuu.one", "ikuuu.pw", "ikuuu.me"] # 备用域名列表
# 统一的User-Agent
USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
+def extract_domains_from_content(content):
+ """
+ 从网页内容中提取可用域名
+ """
+ domains = []
+
+ # 多种域名提取模式
+ patterns = [
+ # 匹配
新域名: xxx.com
或类似格式
+ r']*>.*?(?:域名|domain|新域名|最新域名)[::]\s*([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})',
+ # 匹配JavaScript中的跳转域名
+ r'(?:location\.href|window\.location)\s*=\s*["\']https?://([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})',
+ # 匹配登录链接
+ r'https?://([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})/auth/login',
+ # 匹配任何完整的链接
+ r'https?://([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})',
+ # 匹配文本中的域名描述
+ r'(?:域名|domain|网址|地址)[::\s]*([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})',
+ # 匹配ikuuu相关域名
+ r'(ikuuu\.[a-zA-Z0-9.-]+)',
+ ]
+
+ for pattern in patterns:
+ matches = re.findall(pattern, content, re.IGNORECASE | re.MULTILINE)
+ for match in matches:
+ domain = match.strip().lower()
+ # 过滤掉明显不是域名的内容
+ if (domain and
+ '.' in domain and
+ not domain.startswith('.') and
+ not domain.endswith('.') and
+ len(domain) > 3 and
+ len(domain) < 50 and
+ not any(char in domain for char in [' ', '\n', '\t', '<', '>', '"', "'"])):
+ domains.append(domain)
+
+ # 去重并返回
+ return list(set(domains))
+
+def get_available_domains_from_old_domain(old_domain):
+ """
+ 从旧域名页面获取新的可用域名
+ """
+ available_domains = []
+
+ try:
+ print(f"🔍 从域名 {old_domain} 获取新域名信息...")
+ response = requests.get(f"https://{old_domain}/",
+ headers={"User-Agent": USER_AGENT},
+ timeout=15,
+ allow_redirects=True)
+
+ if response.status_code == 200:
+ content = response.text
+
+ # 检查是否包含域名变更信息
+ change_indicators = [
+ '官网域名已更改', 'Domain deprecated', '域名已更新',
+ '新域名', '最新域名', '域名变更', '网站已迁移'
+ ]
+
+ has_change_info = any(indicator in content for indicator in change_indicators)
+
+ if has_change_info:
+ print("✅ 检测到域名变更通知")
+ domains = extract_domains_from_content(content)
+ available_domains.extend(domains)
+ else:
+ print("ℹ️ 未检测到域名变更通知,但尝试解析可能的域名")
+ domains = extract_domains_from_content(content)
+ # 只保留ikuuu相关域名
+ ikuuu_domains = [d for d in domains if 'ikuuu' in d]
+ available_domains.extend(ikuuu_domains)
+
+ else:
+ print(f"⚠️ 域名 {old_domain} 返回状态码: {response.status_code}")
+
+ except requests.exceptions.Timeout:
+ print(f"⏰ 域名 {old_domain} 请求超时")
+ except requests.exceptions.ConnectionError:
+ print(f"🔌 域名 {old_domain} 连接失败")
+ except Exception as e:
+ print(f"❌ 检查域名 {old_domain} 时出错: {e}")
+
+ return available_domains
+
def get_latest_ikun_host():
+ """
+ 获取最新可用域名
+ """
+ # 首先检查当前域名
test_url = f"https://{ikun_host}/"
try:
response = requests.get(test_url, headers={"User-Agent": USER_AGENT}, timeout=10)
if response.status_code == 200:
- if "官网域名已更改" in response.text or "Domain deprecated" in response.text:
- print("检测到域名变更通知,正在提取新域名...")
- h2_matches = re.findall(r'.*?(?:域名|domain)[::]\s*([a-zA-Z0-9.-]+)
', response.text)
- if h2_matches:
- return h2_matches[0]
- js_matches = re.findall(r'https?://([a-zA-Z0-9.-]+)/auth/login', response.text)
- if js_matches:
- return js_matches[0]
- fallback_match = re.search(r'(?:域名|domain)[::]\s*([a-zA-Z0-9.-]+)', response.text)
- if fallback_match:
- return fallback_match.group(1)
+ # 检查是否有域名变更通知
+ change_indicators = [
+ '官网域名已更改', 'Domain deprecated', '域名已更新',
+ '新域名', '最新域名', '域名变更'
+ ]
+
+ if any(indicator in response.text for indicator in change_indicators):
+ print("🔄 检测到域名变更通知,正在提取新域名...")
+ domains = extract_domains_from_content(response.text)
+
+ # 优先返回ikuuu相关域名
+ for domain in domains:
+ if 'ikuuu' in domain and domain != ikun_host:
+ print(f"🎯 找到新域名: {domain}")
+ return domain
+
+ # 如果没有ikuuu域名,返回第一个有效域名
+ if domains:
+ print(f"🎯 找到域名: {domains[0]}")
+ return domains[0]
+
print("⚠️ 检测到域名变更但无法提取新域名")
return None
else:
print("✅ 当前域名正常")
return None
except Exception as e:
- print(f"域名检测异常: {e}")
+ print(f"🔍 当前域名检测异常: {e}")
+
return None
def update_self_host(new_host):
+ """
+ 更新脚本中的域名
+ """
script_path = os.path.abspath(__file__)
- with open(script_path, "r", encoding="utf-8") as f:
- lines = f.readlines()
- updated = False
- for i, line in enumerate(lines):
- if line.strip().startswith("ikun_host = "):
- lines[i] = f'ikun_host = "{new_host}" # 自动更新于{datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")}\n'
- updated = True
- break
- if updated:
- with open(script_path, "w", encoding="utf-8") as f:
- f.writelines(lines)
- print(f"✅ 脚本已更新至域名: {new_host}")
- return True
- else:
- print("⚠️ 域名更新失败")
+ try:
+ with open(script_path, "r", encoding="utf-8") as f:
+ lines = f.readlines()
+
+ updated = False
+ for i, line in enumerate(lines):
+ if line.strip().startswith("ikun_host = "):
+ lines[i] = f'ikun_host = "{new_host}" # 自动更新于{datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")}\n'
+ updated = True
+ break
+
+ if updated:
+ with open(script_path, "w", encoding="utf-8") as f:
+ f.writelines(lines)
+ print(f"✅ 脚本已更新至域名: {new_host}")
+ return True
+ else:
+ print("⚠️ 未找到域名配置行,无法自动更新")
+ return False
+ except Exception as e:
+ print(f"⚠️ 域名更新失败: {e}")
return False
def test_host_reachable(host):
+ """
+ 测试域名是否可达
+ """
try:
- response = requests.get(f"https://{host}/", headers={"User-Agent": USER_AGENT}, timeout=10)
- return response.status_code == 200
- except:
+ print(f"🔗 测试域名: {host}")
+ response = requests.get(f"https://{host}/",
+ headers={"User-Agent": USER_AGENT},
+ timeout=10)
+ if response.status_code == 200:
+ print(f"✅ 域名 {host} 可用")
+ return True
+ else:
+ print(f"⚠️ 域名 {host} 返回状态码: {response.status_code}")
+ return False
+ except Exception as e:
+ print(f"❌ 域名 {host} 不可用: {e}")
return False
+def find_working_domain():
+ """
+ 寻找可用的域名
+ """
+ global ikun_host
+
+ # 1. 首先检查当前域名
+ print(f"🏠 当前域名: {ikun_host}")
+ if test_host_reachable(ikun_host):
+ return ikun_host
+
+ # 2. 从当前域名和备用域名中获取新域名信息
+ all_domains_to_check = [ikun_host] + backup_hosts
+ discovered_domains = []
+
+ for domain in all_domains_to_check:
+ new_domains = get_available_domains_from_old_domain(domain)
+ discovered_domains.extend(new_domains)
+
+ # 去重
+ discovered_domains = list(set(discovered_domains))
+ print(f"🔍 发现的域名: {discovered_domains}")
+
+ # 3. 测试发现的域名
+ for domain in discovered_domains:
+ if domain != ikun_host and test_host_reachable(domain):
+ print(f"🎉 找到可用域名: {domain}")
+ ikun_host = domain
+ # 尝试更新脚本
+ update_self_host(domain)
+ return domain
+
+ # 4. 测试备用域名
+ print("🔄 测试备用域名列表...")
+ for host in backup_hosts:
+ if host != ikun_host and test_host_reachable(host):
+ print(f"🎉 备用域名可用: {host}")
+ ikun_host = host
+ return host
+
+ # 5. 都不可用
+ print("❌ 所有域名均不可用")
+ return None
+
def get_remaining_flow(cookies):
"""获取用户剩余流量信息"""
user_url = f'https://{ikun_host}/user'
@@ -175,7 +341,7 @@ def ikuuu_signin(email, password):
except Exception as e:
return False, f"请求异常:{str(e)}", "未知", "未知"
-def send_qinglong_notification(results):
+def send_qinglong_notification(results, current_domain):
"""
使用青龙面板内置通知系统发送通知
需要青龙面板已配置通知渠道(如钉钉、企业微信等)
@@ -188,6 +354,7 @@ def send_qinglong_notification(results):
message = [
f"🔔 签到完成 | 成功:{success_count} 失败:{failure_count}",
+ f"🌐 当前域名:{current_domain}",
"================================"
]
@@ -210,27 +377,25 @@ def send_qinglong_notification(results):
print(f"⚠️ 通知发送失败,请检查通知配置: {str(e)}")
if __name__ == "__main__":
- # ==================== 域名更新逻辑 ====================
- print(f"当前域名: {ikun_host}")
+ print("🚀 iKuuu签到脚本启动")
+ print("=" * 50)
+
+ # ==================== 域名检查和更新 ====================
+ # 首先检查是否有域名更新通知
latest_host = get_latest_ikun_host()
- if latest_host:
- print(f"检测到新域名: {latest_host}")
+ if latest_host and latest_host != ikun_host:
+ print(f"🔄 检测到新域名: {latest_host}")
if update_self_host(latest_host):
ikun_host = latest_host
- # ==================== 域名可用性检查 ====================
- if not test_host_reachable(ikun_host):
- print("主域名不可用,尝试备用域名...")
- found = False
- for host in backup_hosts:
- if test_host_reachable(host):
- ikun_host = host
- print(f"切换到备用域名: {ikun_host}")
- found = True
- break
- if not found:
- print("❌ 所有域名均不可用")
- exit(1)
+ # 寻找可用域名
+ working_domain = find_working_domain()
+ if not working_domain:
+ print("💥 无法找到可用域名,脚本退出")
+ exit(1)
+
+ print(f"🎯 使用域名: {working_domain}")
+ print("=" * 50)
# ==================== 账户处理 ====================
accounts = []
@@ -250,10 +415,12 @@ if __name__ == "__main__":
print("❌ 未找到有效账户")
exit(1)
+ print(f"📋 找到 {len(accounts)} 个账户")
+
# ==================== 执行签到 ====================
results = []
- for email, pwd in accounts:
- print(f"\n处理账户: {email}")
+ for index, (email, pwd) in enumerate(accounts, 1):
+ print(f"\n👤 [{index}/{len(accounts)}] 处理账户: {email}")
success, msg, flow_value, flow_unit = ikuuu_signin(email, pwd)
results.append({
'email': email,
@@ -262,20 +429,33 @@ if __name__ == "__main__":
'flow_value': flow_value,
'flow_unit': flow_unit
})
- print(f"结果: {'成功' if success else '失败'} - {msg}")
- print(f"剩余流量: {flow_value} {flow_unit}")
+ status_icon = "✅" if success else "❌"
+ print(f" {status_icon} 结果: {msg}")
+ print(f" 📊 剩余流量: {flow_value} {flow_unit}")
# 账户间延迟防止请求过快
- time.sleep(1)
+ if index < len(accounts): # 最后一个账户不需要延迟
+ time.sleep(2)
# ==================== 结果通知 ====================
- print("\n正在发送通知...")
- send_qinglong_notification(results)
+ print("\n📢 正在发送通知...")
+ send_qinglong_notification(results, working_domain)
# ==================== 本地结果输出 ====================
- print("\n签到结果汇总:")
+ print("\n📊 签到结果汇总:")
+ print("=" * 50)
+ success_count = sum(1 for res in results if res['success'])
+ print(f"🎯 总账户数: {len(results)}")
+ print(f"✅ 成功: {success_count}")
+ print(f"❌ 失败: {len(results) - success_count}")
+ print(f"🌐 使用域名: {working_domain}")
+ print("=" * 50)
+
for res in results:
- print(f"邮箱: {res['email']}")
- print(f"状态: {'成功' if res['success'] else '失败'}")
- print(f"详情: {res['message']}")
- print(f"剩余流量: {res['flow_value']} {res['flow_unit']}\n{'-'*40}")
\ No newline at end of file
+ status_icon = "✅" if res['success'] else "❌"
+ print(f"{status_icon} {res['email']}")
+ print(f" 详情: {res['message']}")
+ print(f" 流量: {res['flow_value']} {res['flow_unit']}")
+
+ print("=" * 50)
+ print("🏁 脚本执行完成")
\ No newline at end of file