認証が必要なサイトを定期スクレイプするとき、難しいのはログイン処理そのものよりログイン状態を維持し続けることだ。クラウドソーシング媒体の案件収集自動化の経緯から、このセッション管理の設計を整理する。
課題: ログイン切れに何度も対処する人間コスト
Bot 対策の CAPTCHA や多要素認証があり、ログインフォームの自動入力は現実的でない。現実的な解は「一度人間がログインし、Cookie を使い続ける」設計だ。Playwright 系のブラウザ自動化ツールはプロファイルディレクトリに Cookie を永続化できる。agent-browser も同じ仕組みで動く。
ただしこの設計の弱点がある。Cookie には有効期限があり、サイト側のセッション管理で任意のタイミングで無効化される。AI エージェントはログイン切れに気づかずスクレイプを続け、ログイン画面へのリダイレクトが混入する。発覚するのは収集データを後から確認したときだ。定期実行の自動化が進むにつれ、対処コストが静かな負債になる。
アプローチ: 2 本の wrapper を責務で分離する
2 本の wrapper スクリプトを分離する設計を採用した。
scripts/research/
├── agent-browser.sh # AI エージェントが使う唯一の正規ルート(headless 強制)
└── agent-browser-login.sh # 人間がログイン切れ時に使う有頭 wrapper
agent-browser.sh は headless モードを強制した安全ラッパーだ。--headed フラグが引数に混入しても除去して無視する。
export AGENT_BROWSER_HEADED=false
exec agent-browser --profile "$PROFILE_DIR" "${args[@]}"
agent-browser-login.sh は有頭モードを使う人間向けの wrapper だ。ログインしたいサイトの URL を引数に渡すと Chrome ウィンドウが開く。人間がログインしてウィンドウを閉じると Cookie がプロファイルに保存され、以降の headless 実行はその Cookie を使う。AI からは呼ばない設計になっている。
役割が明確に分離されているため、「AI が誤って有頭モードで動く」「ログイン用ウィンドウが意図せず閉じられる」といった事故が構造的に起きない。
Chrome プロファイル隔離(—password-store=basic / —use-mock-keychain)
両 wrapper が共有するプロファイルディレクトリは、日常使いの Chrome とは完全に分離している。
分離の理由は二つある。一つは安全性。日常の Chrome に保存された認証情報に AI エージェントからアクセスできる状態は、意図しない操作のリスクを生む。もう一つはheadless 動作の安定性だ。macOS では Chrome のパスワードストアが Keychain に統合されている。headless モードで起動した Chrome がロック状態の Keychain にアクセスしようとすると、認証ダイアログが表示されて処理が止まる。cron から無人で動かすとき、これは致命的だ。
対策として起動フラグで暗号化を無効化する。
--password-store=basic --use-mock-keychain
--password-store=basic は Keychain を使わずプレーンテキスト相当の保存形式を使うよう指示する。--use-mock-keychain は macOS の Keychain 連携をモックに置き換える。wrapper スクリプトがこのフラグを組み込んでいれば、呼び出し側は意識しなくて済む。
hook と組み合わせた pre-check
wrapper の分離だけでは「AI が直接 agent-browser を呼ぶ」経路が残る。これを塞ぐのが PreToolUse hook だ。Bash ツールの実行前に hook スクリプトを介入させ、生の agent-browser コマンドを検出したら exit 2 でブロックする。
[pre-no-raw-agent-browser] Blocked: use scripts/research/agent-browser.sh instead.
hook がガードレールとして機能することで、「wrapper を使う」というルールは AI が守るべき規約ではなく、構造的な強制になる。AI はルールを読んで理解するのではなく、wrapper を使わなければ進めない状態に置かれる。hook の設計思想は別記事「Claude Code 安全運用: PreToolUse hook で AI にガードレールを仕込む」で詳述している。
運用してわかった効果と落とし穴
効果として実感しているのは、ログイン切れへの対処が明確になったことだ。切れたと気づいたら agent-browser-login.sh <url> を実行するだけで回復できる。プロファイルを独立させてから Cookie の寿命パターンも把握しやすくなった。特定の媒体は数日で切れる、別の媒体は数週間持つ、という粒度で経験が蓄積される。
落とし穴として注意が必要なのは、プロファイルディレクトリの扱いだ。Cookie が保存されるためリポジトリには含めない。誤って削除すると全サイトのログイン状態が失われる。もう一つはログイン切れの検出だ。スクレイプが「失敗」するのではなく「ログイン画面を取得して成功する」ケースがある。eval でデータを取り出してもログインフォームのノードしか返ってこない。ナビゲーション内の特定要素の存在確認など、ログイン状態をチェックする pre-check ロジックを入れると堅くなる。
まとめ
認証必須サイトのセッション管理は、設計を整えると運用が安定する。要点は三つだ。
wrapper の分離: headless 強制の AI 向け wrapper と有頭の人間向け relogin wrapper を別ファイルに切り出す。混用事故が起きない。
プロファイル隔離と暗号化フラグ: 日常 Chrome から独立したプロファイルを使い、--password-store=basic --use-mock-keychain で headless の Keychain 問題を回避する。
hook によるガードレール: PreToolUse hook で直接呼び出しをブロックし、wrapper 経由を構造的に強制する。ルールを読んで守るのではなく、守らないと進めない状態を作る。
詳細は「agent-browser を使う理由 — Claude Code でのトークン経済学」と「Claude Code 安全運用: PreToolUse hook で AI にガードレールを仕込む」も参照してほしい。八雲の AI 駆動開発の全体設計についてはハブ記事にまとめている。