From 757ce2f77cc852b7d39ea165cbfa9984c774fcd1 Mon Sep 17 00:00:00 2001 From: Qiufeng Date: Fri, 21 Aug 2026 20:00:59 +0800 Subject: [PATCH] =?UTF-8?q?fix(tencent):=20cookie=5Fauth=20=E6=94=B9?= =?UTF-8?q?=E7=94=A8=20auth=5Fdata=20=E6=8E=A5=E5=8F=A3=E6=8E=A2=E6=B5=8B?= =?UTF-8?q?=E4=B8=BA=E6=9D=83=E5=A8=81=E5=88=A4=E6=8D=AE=EF=BC=8C=E7=A7=BB?= =?UTF-8?q?=E9=99=A4=E4=B8=8D=E5=AD=98=E5=9C=A8=E7=9A=84=E3=80=8C=E5=8F=91?= =?UTF-8?q?=E8=A1=A8=E8=A7=86=E9=A2=91=E3=80=8D=E6=8C=89=E9=92=AE=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=E2=80=94=E2=80=94=E8=AF=A5=E6=8C=89=E9=92=AE=E9=9A=8F?= =?UTF-8?q?=E5=B9=B3=E5=8F=B0=E6=94=B9=E7=89=88=E5=B7=B2=E4=B8=8D=E5=AD=98?= =?UTF-8?q?=E5=9C=A8=EF=BC=8C=E5=AF=BC=E8=87=B4=E7=99=BB=E5=BD=95=E6=88=90?= =?UTF-8?q?=E5=8A=9F=E5=90=8E=E8=AF=AF=E5=88=A4=E5=A4=B1=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- uploader/tencent_uploader/main.py | 46 ++++++++++++++++--------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/uploader/tencent_uploader/main.py b/uploader/tencent_uploader/main.py index 9a48b4c..6930aa2 100644 --- a/uploader/tencent_uploader/main.py +++ b/uploader/tencent_uploader/main.py @@ -155,36 +155,46 @@ def _cookie_auth_via_api(account_file) -> bool | None: async def cookie_auth(account_file): - """视频号登录态校验:接口快速判失效 + 页面验证「发表视频」按钮判登录完整。 + """视频号登录态校验:以 auth_data 接口探测为权威判据。 - 关键:sessionid 有效时接口 auth_data 仍能返回 finder 信息,但 localStorage 登录态 - 不完整(finder_uin 空)时页面会主动弹扫码框、无发表入口——接口层与页面层不一致。 - 因此接口只用于快速判失效,页面验证「发表视频」按钮才是登录完整的可靠标志。 + errCode=0 且 data.finderUser.finderUsername 非空 => 登录完整有效。 + 注意:平台首页 UI(如「发表视频」按钮)随视频号助手改版频繁变动,不能作为稳定判据; + 接口探测基于登录 session 的真实后端校验,才是可靠的登录态信号。 + 仅在接口探测失败(网络异常)时降级为页面行为检测(跳登录页 / 扫码 iframe)。 """ account_file = _resolve_account_file(account_file) - # 1) 接口快速判失效(errCode≠0 或未绑定 finder => 一定失效,无需开浏览器) + # 1) 接口探测(权威判据) via_api = _cookie_auth_via_api(account_file) + if via_api is True: + tencent_logger.success(_msg("🥳", "cookie 有效(接口探测:已登录且绑定视频号身份)")) + return True if via_api is False: tencent_logger.info(_msg("🥹", "cookie 已失效或未绑定视频号身份(接口探测),得重新登录一下")) return False - # 2) 页面验证:登录完整 = 平台首页出现「发表视频」按钮 + # 2) 接口探测失败(None),降级为页面行为检测 async with async_playwright() as playwright: browser = await playwright.chromium.launch(**_build_launch_kwargs(headless=True)) try: context = await browser.new_context(storage_state=account_file) context = await set_init_script(context) page = await context.new_page() - await page.goto(TENCENT_HOME_URL, timeout=120000, wait_until="domcontentloaded") - publish_entry = page.locator("button.weui-desktop-btn", has_text="发表视频").first + await page.goto(TENCENT_HOME_URL, wait_until="domcontentloaded") + # 跳登录页 => 失效 try: - await publish_entry.wait_for(state="visible", timeout=10000) - tencent_logger.success(_msg("🥳", "cookie 有效(平台首页发表入口已加载)")) - return True - except Exception: - tencent_logger.info(_msg("🥹", "cookie 失效(平台首页未加载出发表入口,登录态不完整)")) + await page.wait_for_url("**/login.html**", timeout=8000) + tencent_logger.info(_msg("🥹", "cookie 已失效(页面跳转到登录页),得重新登录一下")) return False + except Exception: + pass + # 页面出现扫码 iframe => 失效 + for fr in page.frames: + if "open.weixin.qq.com/connect/qrconnect" in (fr.url or ""): + tencent_logger.info(_msg("🥹", "cookie 已失效(页面出现扫码框),得重新登录一下")) + return False + tencent_logger.success(_msg("🥳", "cookie 有效")) + return True except Exception as exc: tencent_logger.warning(_msg("😵", f"cookie 校验时出错,按失效处理: {exc}")) return False @@ -304,15 +314,7 @@ async def _is_tencent_login_completed(page: Page, context=None) -> bool: or current_url.startswith(TENCENT_MANAGE_URL) ) - # 1) 平台首页出现「发表视频」按钮 => 登录完整(最可靠,优先) - try: - publish_entry = page.locator("button.weui-desktop-btn", has_text="发表视频").first - if await publish_entry.count() and await publish_entry.is_visible(): - return True - except Exception: - pass - - # 2) 已跳到平台页且无 qrconnect 扫码 iframe => 登录完成 + # 1) 已跳到平台页且无 qrconnect 扫码 iframe => 登录完成 # 注意:登录中的二维码本就嵌在 qrconnect iframe 里,不能把「iframe 存在」当作未登录; # 只有「平台页 + 扫码 iframe 仍在」才视为登录态不完整(页面弹了扫码框) if is_platform: