diff --git a/uploader/tencent_uploader/main.py b/uploader/tencent_uploader/main.py index 1632828..9a48b4c 100644 --- a/uploader/tencent_uploader/main.py +++ b/uploader/tencent_uploader/main.py @@ -298,20 +298,13 @@ async def _has_tencent_login_cookie(context) -> bool: async def _is_tencent_login_completed(page: Page, context=None) -> bool: current_url = page.url or "" - # 1) 仍在登录页 => 未完成(即使 sessionid 已种下,登录流程尚未走完:可能在选号/跳转中) - if "login.html" in current_url: - return False + is_platform = ( + current_url.startswith(TENCENT_HOME_URL) + or current_url.startswith(TENCENT_UPLOAD_URL) + or current_url.startswith(TENCENT_MANAGE_URL) + ) - # 2) 页面仍有 qrconnect 扫码 iframe => 未完成登录(登录态不完整会残留扫码框) - try: - for fr in page.frames: - if "open.weixin.qq.com/connect/qrconnect" in (fr.url or ""): - return False - except Exception: - pass - - # 3) 平台首页出现「发表视频」按钮 => 登录完整(最可靠标志) - # (不完整登录时页面会延迟弹扫码框、且无发表入口) + # 1) 平台首页出现「发表视频」按钮 => 登录完整(最可靠,优先) try: publish_entry = page.locator("button.weui-desktop-btn", has_text="发表视频").first if await publish_entry.count() and await publish_entry.is_visible(): @@ -319,29 +312,24 @@ async def _is_tencent_login_completed(page: Page, context=None) -> bool: except Exception: pass - # 4) localStorage 已有视频号身份(finder_username 非空)=> 登录完整 - try: - finder_username = await page.evaluate("localStorage.getItem('finder_username')") - if finder_username: + # 2) 已跳到平台页且无 qrconnect 扫码 iframe => 登录完成 + # 注意:登录中的二维码本就嵌在 qrconnect iframe 里,不能把「iframe 存在」当作未登录; + # 只有「平台页 + 扫码 iframe 仍在」才视为登录态不完整(页面弹了扫码框) + if is_platform: + try: + has_qr_iframe = any("open.weixin.qq.com/connect/qrconnect" in (fr.url or "") for fr in page.frames) + except Exception: + has_qr_iframe = False + if not has_qr_iframe: return True - except Exception: - pass + # 平台页但扫码 iframe 仍在 => 登录态不完整,视为未完成 + return False - # 5) 已跳到平台页(首页/发布页/列表页)且无可见二维码容器 => 成功 - if current_url.startswith(TENCENT_HOME_URL) or current_url.startswith(TENCENT_UPLOAD_URL) or current_url.startswith(TENCENT_MANAGE_URL): - for marker in [ - page.locator("div.login-qrcode-wrap").first, - page.locator("div.qrcode-wrap").first, - page.locator('span:has-text("微信扫码登录 视频号助手")').first, - ]: - try: - if await marker.count() and await marker.is_visible(): - return False - except Exception: - continue - return True + # 3) 仍在登录页 => 未完成 + if "login.html" in current_url: + return False - # 6) cookie 兜底(已离开登录页且无扫码框) + # 4) cookie 兜底(sessionid 已种下,可能正处于跳转中间态) if context is not None and await _has_tencent_login_cookie(context): return True @@ -355,6 +343,7 @@ async def _is_tencent_qrcode_expired(page: Page) -> bool: 'p.refresh-tip:has-text("二维码已过期,点击刷新")', 'p.refresh-tip:has-text("网络不可用,点击刷新")', ] + # 1) 主页面 for selector in tip_selectors: tip = page.locator(selector).first try: @@ -362,6 +351,16 @@ async def _is_tencent_qrcode_expired(page: Page) -> bool: return True except Exception: continue + # 2) qrconnect iframe 内部(过期/刷新提示显示在 iframe 里) + for fr in page.frames: + if "open.weixin.qq.com/connect/qrconnect" not in (fr.url or ""): + continue + try: + txt = await fr.evaluate("() => document.body ? document.body.innerText : ''") + if any(k in txt for k in ["二维码已过期", "已失效", "点击刷新", "重新扫码"]): + return True + except Exception: + continue return False @@ -370,6 +369,7 @@ async def _is_tencent_qrcode_scanned(page: Page) -> bool: 'div.qr-tip div:has-text("已扫码")', 'div.qr-tip div:has-text("需在手机上进行确认")', ] + # 1) 主页面 for selector in scanned_tips: tip = page.locator(selector).first try: @@ -377,6 +377,16 @@ async def _is_tencent_qrcode_scanned(page: Page) -> bool: return True except Exception: continue + # 2) qrconnect iframe 内部(扫码状态显示在 iframe 里) + for fr in page.frames: + if "open.weixin.qq.com/connect/qrconnect" not in (fr.url or ""): + continue + try: + txt = await fr.evaluate("() => document.body ? document.body.innerText : ''") + if any(k in txt for k in ["已扫码", "扫码成功", "确认登录", "请在手机上确认"]): + return True + except Exception: + continue return False