"""B-3 구독 세션 1회 수동 박제 (MacBook 등 GUI 머신에서 실행). 르몽드 = Google OAuth — 자동화 브라우저 로그인은 Google 이 차단하므로 로그인 자체는 항상 사람이 headed 브라우저에서 수행하고, 본 스크립트는 그 결과(쿠키+localStorage = storage_state JSON)만 박제한다. 사용 (MacBook): pip install playwright && playwright install chromium python scripts/capture_subscription_session.py --profile lemonde --url https://www.lemonde.fr 1) 떠오른 브라우저에서 직접 로그인 (Google OAuth 포함) 2) 로그인 완료 확인 후 터미널에서 Enter 3) ~/.local/share/crawl-auth/lemonde.json 저장 (600) GPU 반영: ssh gpu 'mkdir -p ~/.local/share/crawl-auth && chmod 700 ~/.local/share/crawl-auth' scp ~/.local/share/crawl-auth/lemonde.json gpu:.local/share/crawl-auth/ ssh gpu 'chmod 600 ~/.local/share/crawl-auth/lemonde.json' 세션 만료 후 재로그인도 동일 절차 + source_health.relogin_requested 플래그 set (어댑터가 다음 틱에 half-open probe 로 소비). 주의: storage_state = credential 등가물. repo 안·백업 대상 경로에 두지 말 것. """ import argparse from pathlib import Path from playwright.sync_api import sync_playwright AUTH_DIR = Path.home() / ".local" / "share" / "crawl-auth" def main() -> None: parser = argparse.ArgumentParser(description="B-3 구독 세션 storage_state 박제") parser.add_argument("--profile", required=True, help="예: lemonde") parser.add_argument("--url", required=True, help="로그인 시작 페이지") args = parser.parse_args() AUTH_DIR.mkdir(parents=True, exist_ok=True) AUTH_DIR.chmod(0o700) out = AUTH_DIR / f"{args.profile}.json" with sync_playwright() as pw: browser = pw.chromium.launch(headless=False) context = browser.new_context(viewport={"width": 1366, "height": 900}) page = context.new_page() page.goto(args.url) print(f"\n브라우저에서 로그인을 완료한 뒤 이 터미널에서 Enter 를 누르세요.") input("로그인 완료 후 Enter > ") context.storage_state(path=str(out)) browser.close() out.chmod(0o600) print(f"저장: {out} (600)") print("다음: scp 로 GPU ~/.local/share/crawl-auth/ 반영 + chmod 600") if __name__ == "__main__": main()