"""浏览器管理模块""" import time from DrissionPage import ChromiumPage, ChromiumOptions from logger import get_logger logger = get_logger(__name__) class BrowserManager: """浏览器管理器""" def __init__(self, browser_type: str = 'edge', headless: bool = False): """ 初始化浏览器管理器 Args: browser_type: 浏览器类型 (edge 或 chrome) headless: 是否无头模式 """ self.browser_type = browser_type self.headless = headless self.page = None def init_browser(self): """初始化浏览器""" co = ChromiumOptions() if self.browser_type == 'edge': co.set_browser_path(r"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe") co.set_argument('--no-sandbox') co.set_argument('--disable-dev-shm-usage') if self.headless: co.set_argument('--headless') self.page = ChromiumPage(addr_or_opts=co) logger.info("浏览器初始化成功") def wait_page_loaded(self, timeout=30): """等待页面加载完成""" if self.page: self.page.wait.doc_loaded(timeout=timeout) self.page.ele('tag:body', timeout=timeout) def ensure_connection(self): """确保浏览器连接正常""" try: if self.page: self.page.get("about:blank") return True except: pass try: self.init_browser() self.page.get("about:blank") return True except Exception as e: logger.error(f"无法建立浏览器连接: {e}") return False def import_cookies(self, cookies: list, domain: str): """ 导入cookies到浏览器 Args: cookies: cookie列表 domain: 域名 Returns: 成功导入的cookie数量 """ if not self.ensure_connection(): return 0 if not cookies: return 0 success_count = 0 # 直接使用DrissionPage的set.cookies方法批量导入 # 该方法内部已经优化了导入逻辑 for cookie in cookies: try: if not cookie.get('name') or not cookie.get('value'): continue cookie_dict = { 'name': cookie.get('name'), 'value': cookie.get('value'), 'domain': cookie.get('domain', domain), 'path': cookie.get('path', '/') } self.page.set.cookies(cookie_dict) success_count += 1 except Exception as e: # 忽略导入失败的cookie,继续处理其他cookie pass return success_count def import_local_storage(self, local_storage: dict): """ 导入localStorage到浏览器 Args: local_storage: localStorage字典 Returns: 成功导入的项目数量 """ if not self.ensure_connection(): return 0 ls_count = 0 for domain, items in local_storage.items(): try: for key, value in items.items(): try: self.page.set.local_storage(key, value) ls_count += 1 except Exception as e: logger.error(f"导入localStorage失败: {key} - {e}") except Exception as e: logger.error(f"导入localStorage域失败: {domain} - {e}") logger.info(f"成功导入 {ls_count} 个 localStorage 项目") return ls_count def verify_login(self, url: str, check_selector: str = "", success_text: str = "") -> bool: """ 验证登录状态 Args: url: 网站地址 check_selector: 登录检测选择器 success_text: 登录成功时显示的文本 Returns: 是否已登录 """ if not self.ensure_connection(): return False try: self.page.get(url) self.wait_page_loaded() time.sleep(3) # 等待网页加载完毕并暂停3秒 for i in range(3): time.sleep(3) # 每次刷新前暂停3秒 self.page.refresh() self.wait_page_loaded() time.sleep(3) # 每次刷新后暂停3秒 if not check_selector and not success_text: return False if check_selector: try: element = self.page.ele(check_selector, timeout=10) if element: element_text = element.text or "" if not success_text: return True if success_text in element_text: return True except: pass if success_text: try: page_text = self.page.html or "" if success_text in page_text: return True except: pass return False except Exception as e: logger.error(f"验证登录状态失败: {e}") return False def get_cookies(self) -> list: """ 获取当前浏览器的所有cookies Returns: cookie列表 """ if not self.page: return [] try: return self.page.cookies() except Exception as e: logger.error(f"获取cookies失败: {e}") return [] def get_local_storage(self) -> dict: """ 获取当前浏览器的localStorage Returns: localStorage字典 """ if not self.page: return {} try: import json js_code = """ var result = {}; for (var i = 0; i < localStorage.length; i++) { var key = localStorage.key(i); result[key] = localStorage.getItem(key); } JSON.stringify(result); """ result = self.page.run_js(js_code) return json.loads(result) if result else {} except Exception as e: logger.error(f"获取localStorage失败: {e}") return {} def close(self): """关闭浏览器""" if self.page: try: self.page.quit() except Exception as e: logger.error(f"关闭浏览器失败: {e}") finally: self.page = None