diff --git a/src/gyxx_flow/accounts.py b/src/gyxx_flow/accounts.py index d6b8b48..e57d93a 100644 --- a/src/gyxx_flow/accounts.py +++ b/src/gyxx_flow/accounts.py @@ -479,6 +479,9 @@ class AccountKeepaliveManager: real_chrome=account.keepalive_real_chrome, retries=1, persist_state_on_close=False, + # 目标站点均为国内站,代理出口反被部分 WAF 拉黑(如蝉妈妈 + # TLS reset),账号保活一律直连。 + extra_flags=["--no-proxy-server"], ) try: browser.start() @@ -761,6 +764,8 @@ def login_account( "--remote-debugging-address=127.0.0.1", "--disable-session-crashed-bubble", "--disable-features=InfiniteSessionRestore", + # 国内站直连,避免代理出口被 WAF 拉黑导致登录/探测失败 + "--no-proxy-server", ], ) try: diff --git a/src/gyxx_flow/modules/content_marketing/self_xhs_scraper.py b/src/gyxx_flow/modules/content_marketing/self_xhs_scraper.py index 9efaffd..94d244b 100644 --- a/src/gyxx_flow/modules/content_marketing/self_xhs_scraper.py +++ b/src/gyxx_flow/modules/content_marketing/self_xhs_scraper.py @@ -34,6 +34,7 @@ from gyxx_flow.adapters.scrapling import ( BrowserTimeoutError, # noqa: F401 is_browser_timeout_error, ) +from gyxx_flow.adapters.browser import CookieExpiredError from gyxx_flow.core.exit_codes import COOKIE_SKIP_EXIT_CODE from gyxx_flow.modules.content_marketing import self_operated_accounts from gyxx_flow.modules.content_marketing.runtime_paths import PATHS @@ -375,24 +376,14 @@ def ensure_login(page, login_timeout: int, phone: str) -> None: log(f"[SKIPPED_COOKIE] {reason}") raise AcceptanceCookieSkip(reason) - log("🔄 登录态失效,进入短信验证码登录流程") - page.goto(LOGIN_URL, wait_until="domcontentloaded", timeout=60_000) - page.wait_for_timeout(2000) - # 确保在「短信登录」页签 - for text in ("短信登录",): - try: - tab = page.get_by_text(text, exact=True).first - if tab.count() and tab.is_visible(): - tab.click(timeout=2000) - page.wait_for_timeout(800) - break - except Exception: - continue - _fill_sms_login(page, phone) - wait_for_login(page, login_timeout) - save_state(page) - page.goto(GOODS_URL, wait_until="domcontentloaded", timeout=60_000) - page.wait_for_timeout(2000) + # 采集流程不再内嵌短信验证码登录;统一由 --login-only 手动引导建立登录态。 + reason = ( + "小红书 ARK 后台登录态已失效:请手动执行 " + "`uv run python src/gyxx_flow/modules/content_marketing/self_xhs_scraper.py " + "--login-only` 完成短信验证码登录后重跑" + ) + log(f"[COOKIE_EXPIRED] {reason}") + raise CookieExpiredError(reason) # ============================================================ @@ -855,6 +846,8 @@ def collect(headless: bool, login_timeout: int, max_pages: int, google_search=False, page_setup=restore_cookies, max_pages=3, + # 国内站直连:代理出口被站点 WAF 拉黑时页面/API 直接 ERR_CONNECTION_CLOSED + extra_flags=["--no-proxy-server"], ) as session: page = _open_page(session) ensure_login(page, login_timeout, phone) @@ -927,7 +920,20 @@ def login_only(headless: bool, login_timeout: int) -> int: max_pages=2, ) as session: page = _open_page(session) - ensure_login(page, login_timeout, phone) + page.goto(LOGIN_URL, wait_until="domcontentloaded", timeout=60_000) + page.wait_for_timeout(2000) + for text in ("短信登录",): + try: + tab = page.get_by_text(text, exact=True).first + if tab.count() and tab.is_visible(): + tab.click(timeout=2000) + page.wait_for_timeout(800) + break + except Exception: + continue + _fill_sms_login(page, phone) + wait_for_login(page, login_timeout) + save_state(page) log("✅ 登录态已建立并保存 Cookie") return 0 @@ -953,7 +959,7 @@ def main() -> int: return login_only(args.headless, args.login_timeout) return collect(args.headless, args.login_timeout, args.max_pages, args.dry_run) - except AcceptanceCookieSkip: + except (AcceptanceCookieSkip, CookieExpiredError): return COOKIE_SKIP_EXIT_CODE except KeyboardInterrupt: print("\n⛔ 用户中断", file=sys.stderr)