fix(collect): 账号浏览器与小红书采集强制直连
目标站点均为国内站,Clash 代理出口被蝉妈妈/小红书 WAF 拉黑(TLS 直接 reset, 页面与 API 报 ERR_CONNECTION_CLOSED)。账号保活、扫码登录浏览器与小红书 ARK 采集统一加 --no-proxy-server 直连。
This commit is contained in:
1 parent
41f448420d
commit
1e9ddffd2f
2 files changed
+31
-20
No files matched your search
@@ -479,6 +479,9 @@ class AccountKeepaliveManager:
|
|||||||
real_chrome=account.keepalive_real_chrome,
|
real_chrome=account.keepalive_real_chrome,
|
||||||
retries=1,
|
retries=1,
|
||||||
persist_state_on_close=False,
|
persist_state_on_close=False,
|
||||||
|
# 目标站点均为国内站,代理出口反被部分 WAF 拉黑(如蝉妈妈
|
||||||
|
# TLS reset),账号保活一律直连。
|
||||||
|
extra_flags=["--no-proxy-server"],
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
browser.start()
|
browser.start()
|
||||||
@@ -761,6 +764,8 @@ def login_account(
|
|||||||
"--remote-debugging-address=127.0.0.1",
|
"--remote-debugging-address=127.0.0.1",
|
||||||
"--disable-session-crashed-bubble",
|
"--disable-session-crashed-bubble",
|
||||||
"--disable-features=InfiniteSessionRestore",
|
"--disable-features=InfiniteSessionRestore",
|
||||||
|
# 国内站直连,避免代理出口被 WAF 拉黑导致登录/探测失败
|
||||||
|
"--no-proxy-server",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ from gyxx_flow.adapters.scrapling import (
|
|||||||
BrowserTimeoutError, # noqa: F401
|
BrowserTimeoutError, # noqa: F401
|
||||||
is_browser_timeout_error,
|
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.core.exit_codes import COOKIE_SKIP_EXIT_CODE
|
||||||
from gyxx_flow.modules.content_marketing import self_operated_accounts
|
from gyxx_flow.modules.content_marketing import self_operated_accounts
|
||||||
from gyxx_flow.modules.content_marketing.runtime_paths import PATHS
|
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}")
|
log(f"[SKIPPED_COOKIE] {reason}")
|
||||||
raise AcceptanceCookieSkip(reason)
|
raise AcceptanceCookieSkip(reason)
|
||||||
|
|
||||||
log("🔄 登录态失效,进入短信验证码登录流程")
|
# 采集流程不再内嵌短信验证码登录;统一由 --login-only 手动引导建立登录态。
|
||||||
page.goto(LOGIN_URL, wait_until="domcontentloaded", timeout=60_000)
|
reason = (
|
||||||
page.wait_for_timeout(2000)
|
"小红书 ARK 后台登录态已失效:请手动执行 "
|
||||||
# 确保在「短信登录」页签
|
"`uv run python src/gyxx_flow/modules/content_marketing/self_xhs_scraper.py "
|
||||||
for text in ("短信登录",):
|
"--login-only` 完成短信验证码登录后重跑"
|
||||||
try:
|
)
|
||||||
tab = page.get_by_text(text, exact=True).first
|
log(f"[COOKIE_EXPIRED] {reason}")
|
||||||
if tab.count() and tab.is_visible():
|
raise CookieExpiredError(reason)
|
||||||
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)
|
|
||||||
|
|
||||||
|
|
||||||
# ============================================================
|
# ============================================================
|
||||||
@@ -855,6 +846,8 @@ def collect(headless: bool, login_timeout: int, max_pages: int,
|
|||||||
google_search=False,
|
google_search=False,
|
||||||
page_setup=restore_cookies,
|
page_setup=restore_cookies,
|
||||||
max_pages=3,
|
max_pages=3,
|
||||||
|
# 国内站直连:代理出口被站点 WAF 拉黑时页面/API 直接 ERR_CONNECTION_CLOSED
|
||||||
|
extra_flags=["--no-proxy-server"],
|
||||||
) as session:
|
) as session:
|
||||||
page = _open_page(session)
|
page = _open_page(session)
|
||||||
ensure_login(page, login_timeout, phone)
|
ensure_login(page, login_timeout, phone)
|
||||||
@@ -927,7 +920,20 @@ def login_only(headless: bool, login_timeout: int) -> int:
|
|||||||
max_pages=2,
|
max_pages=2,
|
||||||
) as session:
|
) as session:
|
||||||
page = _open_page(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")
|
log("✅ 登录态已建立并保存 Cookie")
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
@@ -953,7 +959,7 @@ def main() -> int:
|
|||||||
return login_only(args.headless, args.login_timeout)
|
return login_only(args.headless, args.login_timeout)
|
||||||
return collect(args.headless, args.login_timeout, args.max_pages,
|
return collect(args.headless, args.login_timeout, args.max_pages,
|
||||||
args.dry_run)
|
args.dry_run)
|
||||||
except AcceptanceCookieSkip:
|
except (AcceptanceCookieSkip, CookieExpiredError):
|
||||||
return COOKIE_SKIP_EXIT_CODE
|
return COOKIE_SKIP_EXIT_CODE
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print("\n⛔ 用户中断", file=sys.stderr)
|
print("\n⛔ 用户中断", file=sys.stderr)
|
||||||
|
|||||||
Reference in new issue
Block a user