diff --git a/app/helper/cookie.py b/app/helper/cookie.py index 98d67dff..528bc5a7 100644 --- a/app/helper/cookie.py +++ b/app/helper/cookie.py @@ -1,4 +1,5 @@ import base64 +import time from typing import Tuple, Optional from lxml import etree @@ -57,6 +58,36 @@ class CookieHelper: ] } + @staticmethod + def get_page_content(page: BrowserPage, retries: int = 3, interval: float = 1.0) -> Optional[str]: + """ + 获取页面源码,页面跳转中(如登录前后的重定向)会导致 page.content() 抛出 + "Unable to retrieve content because the page is navigating" 异常,等待加载完成后重试 + :param page: 浏览器页面 + :param retries: 最大重试次数 + :param interval: 重试间隔(秒) + :return: 页面源码 + """ + for i in range(retries): + # 等待加载失败不代表源码不可读取,最后一次等待失败时仍尝试直接获取源码 + try: + page.wait_for_load_state("domcontentloaded", timeout=10 * 1000) + except Exception as e: + if i < retries - 1: + logger.warning(f"等待页面加载完成失败:{str(e)},{interval}秒后重试 ({i + 1}/{retries - 1})") + time.sleep(interval) + continue + logger.warning(f"等待页面加载完成失败:{str(e)},尝试直接获取源码") + try: + return page.content() + except Exception as e: + if i >= retries - 1: + logger.error(f"获取页面源码失败:{str(e)}") + return None + logger.warning(f"获取页面源码失败:{str(e)},{interval}秒后重试 ({i + 1}/{retries - 1})") + time.sleep(interval) + return None + @staticmethod def parse_cookies(cookies: list) -> str: """ @@ -93,11 +124,13 @@ class CookieHelper: :return: Cookie和UA """ # 登录页面代码 - html_text = page.content() + html_text = self.get_page_content(page) if not html_text: return None, None, "获取源码失败" # 查找用户名输入框 html = etree.HTML(html_text) + if html is None: + return None, None, "解析网页源码失败" try: username_xpath = None for xpath in self._SITE_LOGIN_XPATH.get("username"): @@ -189,7 +222,12 @@ class CookieHelper: if "verify" in page.url: if not otp_code: return None, None, "需要二次验证码" - html = etree.HTML(page.content()) + html_text = self.get_page_content(page) + if not html_text: + return None, None, "获取网页源码失败" + html = etree.HTML(html_text) + if html is None: + return None, None, "解析网页源码失败" for xpath in self._SITE_LOGIN_XPATH.get("twostep"): if html.xpath(xpath): try: @@ -205,14 +243,17 @@ class CookieHelper: break # 登录后的源码 - html_text = page.content() + html_text = self.get_page_content(page) if not html_text: return None, None, "获取网页源码失败" if SiteUtils.is_logged_in(html_text): return self.parse_cookies(page.context.cookies()), \ page.evaluate("() => window.navigator.userAgent"), "" else: - # 读取错误信息 + # 从登录后的页面读取错误信息 + html = etree.HTML(html_text) + if html is None: + return None, None, "登录失败" error_xpath = None for xpath in self._SITE_LOGIN_XPATH.get("error"): if html.xpath(xpath):