From fbfff5ba213892458e65aea39ae3bd8d12382825 Mon Sep 17 00:00:00 2001 From: UPToZ Date: Fri, 25 Jul 2025 10:08:12 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E6=99=BA=E8=83=BD=E5=9F=9F=E5=90=8D?= =?UTF-8?q?=E5=8F=91=E7=8E=B0=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 多模式域名提取:使用多种正则表达式模式从网页内容中提取域名 自动域名发现:当域名不可用时,会从旧域名页面自动抓取新的可用域名 优先级策略:优先使用ikuuu相关域名,其次使用其他发现的域名 2. 增强的域名检测逻辑 内容解析:能识别多种域名变更通知格式 链接提取:从JavaScript跳转、登录链接等多个位置提取域名 智能过滤:过滤掉无效的域名格式 3. 完善的容错机制 逐步回退:当前域名 → 发现的新域名 → 备用域名列表 连接测试:每个域名都会进行可达性测试 异常处理:增加了超时、连接错误等异常处理 4. 改进的用户体验 详细日志:每个步骤都有清晰的状态提示和图标 进度显示:显示账户处理进度 结果统计:提供详细的执行结果汇总 5. 新增功能 域名信息通知:在通知中包含当前使用的域名 更长延迟:账户间延迟增加到2秒,避免请求过快 更好的错误提示:各种异常情况都有对应的错误信息 --- iKuuu/README.md | 9 ++ iKuuu/ik_signin.py | 302 ++++++++++++++++++++++++++++++++++++--------- 2 files changed, 250 insertions(+), 61 deletions(-) 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