From a7348495c94672e69102fd22f22217e18a0c3195 Mon Sep 17 00:00:00 2001 From: Qiufeng Date: Fri, 21 Aug 2026 18:45:15 +0800 Subject: [PATCH] =?UTF-8?q?fix(tencent):=20=E4=BF=AE=E6=AD=A3=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E5=AE=8C=E6=88=90=E5=88=A4=E5=AE=9A=E9=A1=BA=E5=BA=8F?= =?UTF-8?q?=E2=80=94=E2=80=94=E7=A7=BB=E9=99=A4=20qrconnect=20iframe=20?= =?UTF-8?q?=E5=89=8D=E7=BD=AE=E8=AF=AF=E5=88=A4=EF=BC=8C=E6=94=B9=E4=B8=BA?= =?UTF-8?q?=E5=8F=91=E8=A1=A8=E8=A7=86=E9=A2=91=E6=8C=89=E9=92=AE/?= =?UTF-8?q?=E5=B9=B3=E5=8F=B0=E9=A1=B5=E4=BC=98=E5=85=88=EF=BC=9B=E6=89=AB?= =?UTF-8?q?=E7=A0=81=E4=B8=8E=E8=BF=87=E6=9C=9F=E6=A3=80=E6=B5=8B=E7=A9=BF?= =?UTF-8?q?=E9=80=8F=20iframe=EF=BC=8C=E4=BF=AE=E5=A4=8D=E6=89=AB=E7=A0=81?= =?UTF-8?q?=E5=90=8E=E6=97=A0=E5=8F=8D=E9=A6=88=E3=80=81=E7=99=BB=E5=BD=95?= =?UTF-8?q?=E6=88=90=E5=8A=9F=E5=90=8E=E4=BA=8C=E7=BB=B4=E7=A0=81=E4=B8=8D?= =?UTF-8?q?=E9=94=80=E6=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- uploader/tencent_uploader/main.py | 76 +++++++++++++++++-------------- 1 file changed, 43 insertions(+), 33 deletions(-) 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