diff --git a/app/web.py b/app/web.py index 2fd7c66..dfca37c 100644 --- a/app/web.py +++ b/app/web.py @@ -54,6 +54,8 @@ class AppState: self.event_queue: asyncio.Queue = None self.scraper: Optional[XiaoHongShuScraper] = None self.scraper_task: Optional[asyncio.Task] = None + self.browser = None + self.playwright = None app_state = AppState() @@ -540,71 +542,88 @@ async def check_login_status(): async def verify_login(): """验证登录状态""" try: + # 检查浏览器是否已初始化 + print(f"[DEBUG] 浏览器状态: {app_state.browser is not None}") + # 优先检查浏览器的实际登录状态 - if hasattr(app_state, 'browser') and app_state.browser: + if app_state.browser: try: # 创建新页面检查登录状态 page = await app_state.browser.new_page() + print("[DEBUG] 成功创建新页面") # 访问小红书主页 await page.goto("https://www.xiaohongshu.com/", timeout=10000) + print("[DEBUG] 成功访问小红书主页") # 等待页面加载 - await asyncio.sleep(2) + await asyncio.sleep(3) - # 检查页面标题 + # 获取页面标题和URL title = await page.title() + current_url = page.url - # 如果页面包含"登录"字样,说明未登录 - if "登录" in title or "login" in title.lower(): + print(f"[DEBUG] 页面标题: {title}") + print(f"[DEBUG] 当前URL: {current_url}") + + # 如果被重定向到登录页面或包含登录字样 + if "登录" in title or "login" in title.lower() or "login" in current_url.lower(): + print("[DEBUG] 检测到登录页面,用户未登录") await page.close() return { "success": False, "message": "未找到登录状态,请先登录" } - # 尝试查找已登录的用户标识元素 - try: - # 查找头像或用户名相关元素 - selectors = [ - 'img[src*="avatar"]', - '[class*="avatar"]', - '[class*="user-avatar"]', - '[class*="profile-avatar"]', - '.user-name', - '[class*="username"]' - ] + # 尝试查找已登录的用户标识 + selectors = [ + 'img[src*="avatar"]', + '[class*="avatar"]', + '[class*="user-avatar"]', + '[class*="profile-avatar"]', + '.user-name', + '[class*="username"]', + '.user-nick-name', + '[class*="nick-name"]' + ] - for selector in selectors: - elements = await page.query_selector_all(selector) - if elements: - await page.close() - return { - "success": True, - "message": "登录成功", - "logged_in": True, - "login_time": datetime.now().isoformat(), - "expire_time": (datetime.now() + timedelta(hours=24)).isoformat(), - "expire_in_hours": 24 - } - except: - pass + found_user_elements = False + for selector in selectors: + elements = await page.query_selector_all(selector) + if elements: + print(f"[DEBUG] 找到用户标识: {selector}, 数量: {len(elements)}") + found_user_elements = True + break await page.close() - # 如果能正常访问主页,认为已登录 - return { - "success": True, - "message": "登录成功", - "logged_in": True, - "login_time": datetime.now().isoformat(), - "expire_time": (datetime.now() + timedelta(hours=24)).isoformat(), - "expire_in_hours": 24 - } + if found_user_elements: + print("[DEBUG] 检测到用户标识,认为已登录") + return { + "success": True, + "message": "登录成功", + "logged_in": True, + "login_time": datetime.now().isoformat(), + "expire_time": (datetime.now() + timedelta(hours=24)).isoformat(), + "expire_in_hours": 24 + } + else: + print("[DEBUG] 未找到用户标识,但页面访问正常,认为已登录") + return { + "success": True, + "message": "登录成功", + "logged_in": True, + "login_time": datetime.now().isoformat(), + "expire_time": (datetime.now() + timedelta(hours=24)).isoformat(), + "expire_in_hours": 24 + } except Exception as e: + print(f"[DEBUG] 浏览器访问出错: {str(e)}") # 如果浏览器访问失败,回退到本地文件检查 pass + else: + print("[DEBUG] 浏览器未初始化") # 检查本地登录状态文件(兼容处理) auth_file = os.path.join(config.DATA_DIR, "auth_state.json") @@ -895,6 +914,18 @@ async def startup_event(): # 初始化事件队列 app_state.event_queue = asyncio.Queue() + # 初始化浏览器 + try: + from playwright.async_api import async_playwright + app_state.playwright = await async_playwright().start() + app_state.browser = await app_state.playwright.chromium.launch( + headless=config.HEADLESS, + args=config.BROWSER_ARGS + ) + print("[INFO] 浏览器初始化完成") + except Exception as e: + print(f"[ERROR] 浏览器初始化失败: {str(e)}") + print("=" * 60) print("小红书数据采集器 Web 服务启动") print(f"访问地址: http://{config.WEB_HOST}:{config.WEB_PORT}") @@ -910,6 +941,13 @@ async def shutdown_event(): if app_state.scraper_task: app_state.scraper_task.cancel() + # 关闭浏览器 + if app_state.browser: + await app_state.browser.close() + if app_state.playwright: + await app_state.playwright.stop() + print("[INFO] 浏览器已关闭") + print("Web 服务已关闭")