From 9295e715b500d0b3a2b6efc183ce11eb27cd1696 Mon Sep 17 00:00:00 2001 From: Qiufeng Date: Fri, 21 Aug 2026 17:07:18 +0800 Subject: [PATCH] =?UTF-8?q?fix(tencent):=20=E7=99=BB=E5=BD=95=E6=88=90?= =?UTF-8?q?=E5=8A=9F=E6=94=B9=E4=B8=BA=20cookie=20=E6=A3=80=E6=B5=8B?= =?UTF-8?q?=E4=BC=98=E5=85=88=EF=BC=88ww=5Fdatasalt/ww=5Fbizuin/wxuin/slav?= =?UTF-8?q?e=5Fsid=EF=BC=89=EF=BC=8C=E4=BF=AE=E5=A4=8D=E6=89=AB=E7=A0=81?= =?UTF-8?q?=E7=A1=AE=E8=AE=A4=E5=90=8E=20DOM/URL=20=E6=A3=80=E6=B5=8B?= =?UTF-8?q?=E4=B8=8D=E5=88=B0=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- uploader/tencent_uploader/main.py | 74 +++++++++++++++---------------- 1 file changed, 35 insertions(+), 39 deletions(-) diff --git a/uploader/tencent_uploader/main.py b/uploader/tencent_uploader/main.py index 1a08c24..82ff074 100644 --- a/uploader/tencent_uploader/main.py +++ b/uploader/tencent_uploader/main.py @@ -235,51 +235,45 @@ async def _save_tencent_qrcode(page: Page, account_file: str, previous_qrcode_pa return qrcode_info -async def _is_tencent_login_completed(page: Page) -> bool: - # 仍在登录页(含扫码 iframe)=> 未登录 +# 微信扫码登录成功后,视频号助手(channels.weixin.qq.com)域下必然种下这些登录态 cookie; +# 用 cookie 判定登录成功最可靠,不依赖页面 DOM/URL(登录后落地页可能停在首页、残留 iframe 等) +_TENCENT_LOGIN_COOKIE_MARKERS = {"ww_datasalt", "ww_bizuin", "wxuin", "slave_sid", "slave_user"} + + +async def _has_tencent_login_cookie(context) -> bool: + try: + cookies = await context.cookies() + names = {c["name"] for c in cookies} + return bool(names & _TENCENT_LOGIN_COOKIE_MARKERS) + except Exception: + return False + + +async def _is_tencent_login_completed(page: Page, context=None) -> bool: + # 首选:登录态 cookie 出现即视为成功(扫码+手机确认后浏览器必种 cookie) + if context is not None and await _has_tencent_login_cookie(context): + return True + current_url = page.url or "" + # 仍在登录页 => 未登录 if "login.html" in current_url: return False - # 页面内还存在微信扫码登录 iframe => 未登录 - try: - for fr in page.frames: - if "open.weixin.qq.com/connect/qrconnect" in (fr.url or ""): - return False - except Exception: - pass - - # 页面内还存在登录二维码容器 => 未登录 - login_markers = [ - page.locator("div.login-qrcode-wrap").first, - page.locator("div.qrcode-wrap").first, - page.locator('span:has-text("微信扫码登录 视频号助手")').first, - ] - for marker in login_markers: - try: - if await marker.count() and await marker.is_visible(): - return False - except Exception: - continue - - # 已离开登录页且登录框/二维码均消失 => 视为登录成功 - # (视频号登录后通常停在 /platform 首页,不一定跳到 post/create 或 post/list) + # 已跳到平台页(首页/发布页/列表页):只要没有可见的二维码容器就算成功 + # 注意:残留的扫码 iframe 只隐藏未移除时也会在 page.frames 里,不能作为否决条件 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 - # 兜底:出现发布相关按钮也视为成功 - publish_markers = [ - page.locator('div:has-text("发表视频")').first, - page.locator('button:has-text("发表")').first, - page.locator('button:has-text("保存草稿")').first, - ] - for marker in publish_markers: - try: - if await marker.count() and await marker.is_visible(): - return True - except Exception: - continue - return False @@ -360,6 +354,7 @@ async def _refresh_tencent_qrcode(page: Page) -> None: async def _wait_for_tencent_login( page: Page, + context, account_file: str, qrcode_info: dict | None, qrcode_callback=None, @@ -369,7 +364,7 @@ async def _wait_for_tencent_login( qrcode_path = Path(qrcode_info["image_path"]) if qrcode_info else None scanned_logged = False for _ in range(max_checks): - if await _is_tencent_login_completed(page): + if await _is_tencent_login_completed(page, context): tencent_logger.info(_msg("🥳", f"扫码成功,已经跳转到登录后页面: {page.url}")) return _build_login_result(True, "success", "视频号扫码登录成功", account_file, qrcode_info, page.url) @@ -433,6 +428,7 @@ async def tencent_cookie_gen( tencent_logger.info(_msg("🧍", "请扫码,小人正在耐心等待登录完成")) result = await _wait_for_tencent_login( page, + context, account_file, qrcode_info, qrcode_callback=qrcode_callback,