"""Cookie 监控主程序""" import json from datetime import datetime from cookie_cloud import CookieCloud from notifier import IYUUNotifier, FailureTracker from browser_login import BrowserLogin, CookieManager from applogger import setup_logging, get_logger logger = get_logger(__name__) class CookieMonitor: """Cookie 监控器""" def __init__(self, config_file: str = "config.json"): self.config_file = config_file self.config = self._load_config() self.cookie_manager = CookieManager("cookies.json") self.failure_tracker = FailureTracker("state.json") def _load_config(self) -> dict: try: with open(self.config_file, 'r', encoding='utf-8') as f: return json.load(f) except Exception as e: logger.error(f"加载配置文件失败: {e}") return {} def _get_domain_from_url(self, url: str) -> str: from urllib.parse import urlparse return urlparse(url).netloc def process_user(self, user_config: dict): """ 处理单个用户:一次性导入所有cookies,然后验证各网站登录状态 """ user_name = user_config.get('name', '未知用户') logger.info(f"{'='*20} 开始处理用户: {user_name} {'='*20}") cookie_cloud_config = user_config.get('cookie_cloud', {}) notification_config = user_config.get('notification', {}) browser_config = user_config.get('browser', {}) websites = user_config.get('websites', []) if not websites: logger.info(f"用户 {user_name} 没有配置网站,跳过") return iyuu_token = notification_config.get('iyuu_token', '') max_fail_count = notification_config.get('max_fail_count', 3) notifier = IYUUNotifier(iyuu_token) if iyuu_token else None cookie_cloud = CookieCloud( api_url=cookie_cloud_config.get('api_url', ''), uuid=cookie_cloud_config.get('uuid', ''), password=cookie_cloud_config.get('password', '') ) logger.info(f"步骤1: 从 Cookie Cloud 获取所有 cookies") all_cookies = cookie_cloud.get_cookies() total_domains = len(all_cookies) total_cookies = sum(len(c) for c in all_cookies.values()) logger.info(f"获取到 {total_domains} 个域名,共 {total_cookies} 个 cookie") browser = BrowserLogin( browser_type=browser_config.get('type', 'edge'), headless=browser_config.get('headless', False) ) results = [] try: logger.info(f"步骤2: 一次性导入所有 cookies 到浏览器") all_cookies_list = [] for cookies in all_cookies.values(): all_cookies_list.extend(cookies) import_success = browser.import_all_cookies(all_cookies_list) if import_success: logger.info(f"成功导入 {len(all_cookies_list)} 个 cookie") else: logger.warning(f"部分 cookie 导入失败") logger.info(f"步骤3: 依次验证各网站登录状态") for website in websites: result = self.process_website( user_name=user_name, website_config=website, browser=browser ) results.append(result) if not result['success']: self.failure_tracker.check_and_notify( user_name=user_name, website_name=result['name'], max_fail_count=max_fail_count, notifier=notifier, error_msg=result['error'] ) else: self.failure_tracker.reset_fail_count(user_name, result['name']) self._print_summary(user_name, results) finally: browser.close() def process_website( self, user_name: str, website_config: dict, browser: BrowserLogin ) -> dict: """ 验证网站登录状态(cookies已预先导入) Returns: dict: {'name': 网站名, 'url': URL, 'success': 是否成功, 'error': 错误信息} """ website_name = website_config.get('name', '未知网站') url = website_config.get('url', '') check_selector = website_config.get('login_check_selector', '') success_text = website_config.get('success_text', '') logger.info(f"\n验证网站: {website_name}") logger.info(f" URL: {url}") result = { 'name': website_name, 'url': url, 'success': False, 'error': '' } if not url: result['error'] = 'URL 未配置' logger.error(f" 失败: {result['error']}") return result try: login_success = browser.verify_login( url=url, check_selector=check_selector, success_text=success_text ) if login_success: result['success'] = True logger.info(f" ✓ 登录验证成功") new_cookies = browser.refresh_and_save_cookies(url) if new_cookies: self.cookie_manager.save_cookies(user_name, website_name, new_cookies) logger.info(f" 已保存 {len(new_cookies)} 个新 cookie") else: result['error'] = '登录状态验证失败(cookies可能已过期或选择器配置错误)' logger.warning(f" ✗ {result['error']}") except Exception as e: result['error'] = f'处理异常: {str(e)}' logger.error(f" 异常: {e}") return result def _print_summary(self, user_name: str, results: list): """打印处理结果汇总""" success_count = sum(1 for r in results if r['success']) fail_count = len(results) - success_count logger.info(f"\n{'='*20} 用户 {user_name} 处理结果汇总 {'='*20}") logger.info(f"总网站数: {len(results)}") logger.info(f"成功: {success_count}, 失败: {fail_count}") if fail_count > 0: logger.info("\n失败详情:") for r in results: if not r['success']: logger.info(f" - {r['name']}: {r['error']}") def run(self): """运行监控""" logger.info("="*50) logger.info("Cookie 监控开始") logger.info(f"时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") logger.info("="*50) users = self.config.get('users', []) if not users: logger.error("未找到用户配置") return for user_config in users: try: self.process_user(user_config) except Exception as e: logger.error(f"处理用户失败: {e}") logger.info("\n" + "="*50) logger.info("Cookie 监控结束") logger.info("="*50) def main(): setup_logging() monitor = CookieMonitor() monitor.run() if __name__ == "__main__": main()