fix(tencent): cookie_auth 改用 auth_data 接口探测为权威判据,移除不存在的「发表视频」按钮验证——该按钮随平台改版已不存在,导致登录成功后误判失效
This commit is contained in:
@@ -155,36 +155,46 @@ def _cookie_auth_via_api(account_file) -> bool | None:
|
|||||||
|
|
||||||
|
|
||||||
async def cookie_auth(account_file):
|
async def cookie_auth(account_file):
|
||||||
"""视频号登录态校验:接口快速判失效 + 页面验证「发表视频」按钮判登录完整。
|
"""视频号登录态校验:以 auth_data 接口探测为权威判据。
|
||||||
|
|
||||||
关键:sessionid 有效时接口 auth_data 仍能返回 finder 信息,但 localStorage 登录态
|
errCode=0 且 data.finderUser.finderUsername 非空 => 登录完整有效。
|
||||||
不完整(finder_uin 空)时页面会主动弹扫码框、无发表入口——接口层与页面层不一致。
|
注意:平台首页 UI(如「发表视频」按钮)随视频号助手改版频繁变动,不能作为稳定判据;
|
||||||
因此接口只用于快速判失效,页面验证「发表视频」按钮才是登录完整的可靠标志。
|
接口探测基于登录 session 的真实后端校验,才是可靠的登录态信号。
|
||||||
|
仅在接口探测失败(网络异常)时降级为页面行为检测(跳登录页 / 扫码 iframe)。
|
||||||
"""
|
"""
|
||||||
account_file = _resolve_account_file(account_file)
|
account_file = _resolve_account_file(account_file)
|
||||||
|
|
||||||
# 1) 接口快速判失效(errCode≠0 或未绑定 finder => 一定失效,无需开浏览器)
|
# 1) 接口探测(权威判据)
|
||||||
via_api = _cookie_auth_via_api(account_file)
|
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:
|
if via_api is False:
|
||||||
tencent_logger.info(_msg("🥹", "cookie 已失效或未绑定视频号身份(接口探测),得重新登录一下"))
|
tencent_logger.info(_msg("🥹", "cookie 已失效或未绑定视频号身份(接口探测),得重新登录一下"))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# 2) 页面验证:登录完整 = 平台首页出现「发表视频」按钮
|
# 2) 接口探测失败(None),降级为页面行为检测
|
||||||
async with async_playwright() as playwright:
|
async with async_playwright() as playwright:
|
||||||
browser = await playwright.chromium.launch(**_build_launch_kwargs(headless=True))
|
browser = await playwright.chromium.launch(**_build_launch_kwargs(headless=True))
|
||||||
try:
|
try:
|
||||||
context = await browser.new_context(storage_state=account_file)
|
context = await browser.new_context(storage_state=account_file)
|
||||||
context = await set_init_script(context)
|
context = await set_init_script(context)
|
||||||
page = await context.new_page()
|
page = await context.new_page()
|
||||||
await page.goto(TENCENT_HOME_URL, timeout=120000, wait_until="domcontentloaded")
|
await page.goto(TENCENT_HOME_URL, wait_until="domcontentloaded")
|
||||||
publish_entry = page.locator("button.weui-desktop-btn", has_text="发表视频").first
|
# 跳登录页 => 失效
|
||||||
try:
|
try:
|
||||||
await publish_entry.wait_for(state="visible", timeout=10000)
|
await page.wait_for_url("**/login.html**", timeout=8000)
|
||||||
tencent_logger.success(_msg("🥳", "cookie 有效(平台首页发表入口已加载)"))
|
tencent_logger.info(_msg("🥹", "cookie 已失效(页面跳转到登录页),得重新登录一下"))
|
||||||
return True
|
|
||||||
except Exception:
|
|
||||||
tencent_logger.info(_msg("🥹", "cookie 失效(平台首页未加载出发表入口,登录态不完整)"))
|
|
||||||
return False
|
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:
|
except Exception as exc:
|
||||||
tencent_logger.warning(_msg("😵", f"cookie 校验时出错,按失效处理: {exc}"))
|
tencent_logger.warning(_msg("😵", f"cookie 校验时出错,按失效处理: {exc}"))
|
||||||
return False
|
return False
|
||||||
@@ -304,15 +314,7 @@ async def _is_tencent_login_completed(page: Page, context=None) -> bool:
|
|||||||
or current_url.startswith(TENCENT_MANAGE_URL)
|
or current_url.startswith(TENCENT_MANAGE_URL)
|
||||||
)
|
)
|
||||||
|
|
||||||
# 1) 平台首页出现「发表视频」按钮 => 登录完整(最可靠,优先)
|
# 1) 已跳到平台页且无 qrconnect 扫码 iframe => 登录完成
|
||||||
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 => 登录完成
|
|
||||||
# 注意:登录中的二维码本就嵌在 qrconnect iframe 里,不能把「iframe 存在」当作未登录;
|
# 注意:登录中的二维码本就嵌在 qrconnect iframe 里,不能把「iframe 存在」当作未登录;
|
||||||
# 只有「平台页 + 扫码 iframe 仍在」才视为登录态不完整(页面弹了扫码框)
|
# 只有「平台页 + 扫码 iframe 仍在」才视为登录态不完整(页面弹了扫码框)
|
||||||
if is_platform:
|
if is_platform:
|
||||||
|
|||||||
Reference in New Issue
Block a user