Merge branch 'main' into fix/douyin-cli-login-overhaul

This commit is contained in:
Alleria
2026-06-27 01:15:42 +08:00
committed by GitHub
12 changed files with 581 additions and 29 deletions
+21 -21
View File
@@ -49,28 +49,28 @@ def _build_login_result(success: bool, status: str, message: str, account_file:
async def cookie_auth(account_file):
async with async_playwright() as playwright:
# 抖音无头会撞反爬墙→content/upload 跳登录→误判 cookie 失效(间歇性)。校验必须有头。
# 允许 linux server 用户通过 env var 强制无头: DOUYIN_COOKIE_AUTH_HEADLESS=true
use_headless = os.environ.get("DOUYIN_COOKIE_AUTH_HEADLESS", "").lower() in ("1", "true", "yes")
launch_kwargs = {"headless": use_headless, "channel": "chrome", "args": ["--no-sandbox", "--disable-blink-features=AutomationControlled"]}
browser = await playwright.chromium.launch(**launch_kwargs)
try:
context = await browser.new_context(storage_state=account_file)
context = await set_init_script(context)
page = await context.new_page()
await page.goto("https://creator.douyin.com/creator-micro/content/upload", wait_until="domcontentloaded", timeout=15000)
# SPA 跳转是异步的,count() 在 race window 内可能为 0 → 假阳性。
# 改为轮询:最多 10s 内任一稳定文字出现即返回;超时保守判失效。
for _ in range(20):
if await page.get_by_text("扫码登录").count() or await page.get_by_text("手机号登录").count():
return False
if await page.get_by_text("上传视频").count():
# 抖音无头会撞反爬墙→content/upload 跳登录→误判 cookie 失效(间歇性)。校验必须有头。
# 即便有头,页面慢/瞬时跳转仍会让 wait_for_url(精确URL,5s) 误判→重试3次+宽松判定(URL含 content/upload 且无登录文案)。
# 允许 linux server 用户通过 env var 强制无头: DOUYIN_COOKIE_AUTH_HEADLESS=true
use_headless = os.environ.get("DOUYIN_COOKIE_AUTH_HEADLESS", "").lower() in ("1", "true", "yes")
launch_kwargs = {"headless": use_headless, "channel": "chrome", "args": ["--no-sandbox", "--disable-blink-features=AutomationControlled"]}
for _attempt in range(3):
async with async_playwright() as playwright:
browser = await playwright.chromium.launch(**launch_kwargs)
try:
context = await browser.new_context(storage_state=account_file)
context = await set_init_script(context)
page = await context.new_page()
await page.goto("https://creator.douyin.com/creator-micro/content/upload", wait_until="domcontentloaded", timeout=90000)
await page.wait_for_timeout(2500) # 等页面稳定,避免瞬时跳转误判
has_login = await page.get_by_text("手机号登录").count() or await page.get_by_text("扫码登录").count()
if "content/upload" in page.url and not has_login:
return True
await asyncio.sleep(0.5)
return False
finally:
await browser.close()
except Exception:
pass
finally:
await browser.close()
return False
async def douyin_setup(account_file, handle=False, return_detail=False, qrcode_callback=None, headless: bool = LOCAL_CHROME_HEADLESS, cdp_url: str | None = None):