マキモノ
データ収集無料✅ 公式検証済みv1.0.0 / 更新

reCAPTCHA のあるサイトを AI に何度も読ませる:ログイン窓をセッションから切り離して常駐させる

Playwright の launchPersistentContext は親プロセスが死ぬとブラウザも死ぬため、AI エージェントのセッションが変わるたびに人が reCAPTCHA を押し直すことになる。detached 起動+CDP 接続、プロファイル固定とログイン保持、管理者権限を使わないログオン常駐の3層で解消する手順。exit code 契約と、実際に壊して確かめる検証手順つき。

出品者: seisaku-team@orgiast.jp📖 読込 約2,964トークン (約4円)💰 コスパ 13
トークン節約メーター89%節約
ゼロからAIに作らせた場合4.2万トークン
このMDを読ませた場合4,500トークン

3.8万トークンの節約 (API料金換算で約56円分)。 要件定義・技術調査・試行錯誤ぶんのトークンがまるごと不要になります。※ 出品者申告とレビューに基づく推定値。モデル・タスク内容により変動します。

この巻物について

reCAPTCHA のあるサイトを AI に何度も読ませる:ログイン窓をセッションから切り離して常駐させる」は、データ収集カテゴリのAI指示書(MDファイル)です。Playwright の launchPersistentContext は親プロセスが死ぬとブラウザも死ぬため、AI エージェントのセッションが変わるたびに人が reCAPTCHA を押し直すことになる。detached 起動+CDP 接続、プロファイル固定とログイン保持、管理者権限を使わないログオン常駐の3層で解消する手順。exit code 契約と、実際に壊して確かめる検証手順つき。この巻物をAIに読み込ませると、ゼロから設計・調査する場合に比べて 約3.8万トークン(API料金換算で約56円)・89%のトークンを節約できます。

カテゴリ
データ収集
対応AI
claude-code、cursor、codex-cli
ライセンス
商用利用可 (再販不可)
価格
無料
ゼロから開発時
約4.2万トークン
この巻物使用時
約4,500トークン
節約量
約3.8万トークン (約56円)
更新日
2026-09-03

使い方 (AIに渡す3つの方法)

いちばん簡単なのはワンライナー。Claude Code のターミナルに貼るだけです。

⬇ .md をダウンロード
claude "https://makimono-md.vercel.app/api/v1/files/recaptcha-ai/raw を読み込んで、この指示書どおりに実装して"
claude-codecursorcodex-cliライセンス: 商用利用可 (再販不可)

中身

reCAPTCHA のあるサイトを AI に何度も読ませる:ログイン窓を「セッションから切り離して」常駐させる

この指示書が解く問題

AI エージェント(Claude Code / Cursor / 自作エージェント)に、管理画面を繰り返し読ませたい。 だが対象サイトのログインに reCAPTCHA があり、自動ログインできない。人が1回押せばいい話なのに、 エージェントのセッションが終わるたびに押し直すことになる。1日に何度も起きる。

原因はほぼ確実にこれ。Playwright の launchPersistentContext で開いたブラウザは 呼び出したプロセスの子になる。エージェントのシェルが終わればブラウザも死ぬ。 プロファイル(Cookie)は残っているのに、窓が消えるので押し直しになる。

直し方は3層。この3つを全部やって初めて「切れない」と言える。

切れ方対策
エージェントのセッション終了で死ぬブラウザを detached で起動し、CDP で後から繋ぐ
ブラウザを閉じる・落ちると死ぬプロファイルを固定し、サイトの「ログイン状態を保持」を必ず ON にする
OS 再起動で死ぬログオン時に起こし直す常駐(管理者権限を使わない方法がある)

1. detached で起動して CDP で繋ぐ

launchPersistentContext を捨てる。ブラウザの実行ファイルを自分で spawn する。

import { chromium } from 'playwright';
import { spawn } from 'node:child_process';

const CDP_PORT = 9222;
const PROFILE_DIR = '<固定プロファイルの絶対パス>';   // 例: <ホーム>/.agent/<サイト名>-profile

async function cdpAlive() {
  try {
    const res = await fetch(`http://127.0.0.1:${CDP_PORT}/json/version`,
                            { signal: AbortSignal.timeout(3000) });
    return res.ok;
  } catch { return false; }
}

async function launch() {
  const exe = chromium.executablePath();          // Playwright が入れた実行ファイル
  const child = spawn(exe, [
    `--remote-debugging-port=${CDP_PORT}`,
    `--user-data-dir=${PROFILE_DIR}`,
    '--no-first-run',
    '--no-default-browser-check',
    '--disable-blink-features=AutomationControlled',
    'about:blank',
  ], { detached: true, stdio: 'ignore' });          // ← ここが本質
  child.unref();                                   // ← 親が待たない

  for (let i = 0; i < 60; i++) {                   // 最大30秒待つ
    if (await cdpAlive()) return true;
    await new Promise(r => setTimeout(r, 500));
  }
  return false;
}

// 以降は「生きているブラウザに繋ぐ」だけ
const browser = await chromium.connectOverCDP(`http://127.0.0.1:${CDP_PORT}`);
const context = browser.contexts()[0];
const page = await context.newPage();              // 既存タブを奪わない

落とし穴(ここで必ず1回は転ぶ)

  • connectOverCDP の戻り値に browser.close() を呼んではいけない。 常駐ブラウザが死ぬ。 閉じるのは newPage() で自分が開いたタブだけ。finallybrowser.close() を 書いてしまうのが定番事故。
  • pages()[0] を使うな。 他の処理が開いているタブを奪って表示を壊す。必ず newPage()
  • detached になったかはコードでなくプロセスの親で検証する。 デバッグポートを持つブラウザの root プロセスの ParentProcessId を調べ、 その親が終了済みなら成功。親がまだ自分のランタイムなら失敗している。 Windows なら: Get-CimInstance Win32_Process -Filter "Name='chrome.exe'"CommandLineremote-debugging-port で絞り、ParentProcessId の生存を見る。
  • 二重起動を必ずガードする。 同じプロファイルを後から掴んだブラウザは 先に起動していたプロセスを掃除する。人がログイン待ちだった窓ごと消える。 起動前に必ず CDP の生死を見て、生きていれば起動しない。

2. 人の1クリックまで全部お膳立てする

未ログインなら、押す以外のことは全部機械がやる

// value への直代入は input イベントが飛ばず、サイト側の JS が「未入力」と見なすことがある。
// 必ず fill を使う。
await page.fill('input[name="<ユーザー名欄>"]', creds.username);
await page.fill('input[name="<パスワード欄>"]', creds.password);

// 「ログイン状態を保持」を必ず ON にする。これが Cookie を長生きさせる肝。
const keep = await page.$('input[type="checkbox"]');
if (keep && !(await keep.isChecked())) await keep.check();

await page.bringToFront();       // 人に押してもらうときだけ前面へ
// reCAPTCHA と送信ボタンは押さない。迂回しない。

資格情報はリポジトリに置かない。 ホーム配下の JSON などに置き、そこから読む。

状態を exit code で外に出す

エージェントが判断できるように、状態を終了コードで返す。ログ文字列で判定させない。

0 = ログイン済み(そのまま読める)
1 = ブラウザは生きているが未ログイン(人が1クリックする必要がある)
2 = ブラウザに繋げない/起動できない/資格情報が無い

加えて状態を JSON ファイルに書いておくと、別のツールから参照できる。

{ "checkedAt": "...", "cdpUp": true, "loggedIn": false, "launched": false, "tabs": 1 }

ログイン判定は「パスワード欄が無い」だけでは足りない。 多くのサイトは 「メールを確認してください」の踊り場を挟み、そこにもパスワード欄が無いので誤って成功と判定する。 パスワード欄の有無踊り場の文言本文の長さ の3つで見る。


3. OS 再起動対策:管理者権限を使わない

タスクスケジューラ(Register-ScheduledTask)は昇格していないシェルでは アクセスが拒否されました(HRESULT 0x80070005)で落ちる。人に管理者シェルを開かせるのは 手間が増えるだけなので、ユーザーのスタートアップフォルダを使う。昇格が一切不要。

%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\<名前>.vbs:

' ASCII only. cscript/wscript mis-reads UTF-8 with BOM.
Option Explicit
Dim sh
Set sh = CreateObject("WScript.Shell")
Do
  On Error Resume Next
  sh.CurrentDirectory = "<ツールのある絶対パス>"
  ' 0 = hidden, True = wait so instances never stack up
  sh.Run "cmd /c node <ツール> --ensure --no-front", 0, True
  On Error Goto 0
  WScript.Sleep 1800000    ' 30 min
Loop
  • VBS の中身は ASCII だけにする。 BOM 付き UTF-8 を誤読して何も実行しない。
  • 定期実行では前面に出さない--no-front のようなフラグを用意する)。 30分ごとにフォーカスを奪うと人の作業を邪魔して、結局止められる。
  • 消したいときはこの1ファイルを削除するだけにする。可逆にしておく。

macOS / Linux なら launchd の RunAtLoad / systemd の user unit(systemctl --user)で同じことをやる。 どちらも root 不要。


4. 「切れなくなった」と言う前に必ず実測する

3つとも実際に壊してから直るかを見る。コードを読んで納得しただけで報告してはいけない。

検証やり方合格
セッション終了に耐えるブラウザ root プロセスの親を調べる親が終了済み
ブラウザ再起動に耐えるそのプロファイルのブラウザだけを全部落として起こし直す状態確認が exit 0
OS 再起動に耐えるブラウザを落とし、常駐スクリプトだけを起動する数十秒で復活する

プロセスを落とすときは、必ず CommandLine にそのプロファイルのパスを含むものだけに絞る。 人が普段使いのブラウザを何十本も開いていることがある。名前だけで Stop-Process すると 仕事中のタブを全部消す。

「プロファイルを共有しても別プロセスでは未ログイン扱いになった」という観測は、 headless で起動していたことが原因である場合が多い。detached の非 headless 起動なら持続する。 過去の観測を持ち出して諦める前に、起動方法を変えて再検証する。


5. 得られる形

node <ツール> --status    # 見るだけ。0=ログイン済み 1=未ログイン 2=繋げない
node <ツール> --ensure    # 落ちていたら起こす+入力を埋めて前面へ
node <ツール> --ensure --no-front --shot out.png   # 常駐用/実表示の記録

エージェント側は着手前に --status を叩き、exit 0 ならそのまま読む。 exit 1 のときだけスクショを撮って自分で目視してから、人に「1クリック」を頼む。 画面を見ずに手順を書くと、実在しないラベル名を書いて人に手戻りをさせる。

これで人の操作は「サイトがログインを失効させたとき、1回だけ」に減る。

よくある質問

「reCAPTCHA のあるサイトを AI に何度も読ませる:ログイン窓をセッションから切り離して常駐させる」とは何ですか?

Playwright の launchPersistentContext は親プロセスが死ぬとブラウザも死ぬため、AI エージェントのセッションが変わるたびに人が reCAPTCHA を押し直すことになる。detached 起動+CDP 接続、プロファイル固定とログイン保持、管理者権限を使わないログオン常駐の3層で解消する手順。exit code 契約と、実際に壊して確かめる検証手順つき。

どれくらいトークン(費用)を節約できますか?

ゼロから開発すると約4.2万トークンかかりますが、この巻物を使えば約4,500トークンで済みます。差し引き約3.8万トークン(API料金換算で約56円)・89%の節約です。

どうやって使いますか?

無料です。MDファイルを Claude Code などのAIに読み込ませるだけ。ワンライナーをターミナルに貼れば実装が始まります。要件定義や技術調査を省いて実装だけにトークンを使えます。

どのAIツールに対応していますか?

claude-code、cursor、codex-cli に対応しています。

商用利用できますか?

ライセンスは「商用利用可 (再販不可)」です。

🤝 自分でAIを動かすのは、まだ不安…という方へ

この巻物の内容を、AIを使うプロに丸ごと任せることもできます。姉妹サービスAI代行堂なら「LINEで頼むだけで、仕事が完成」。

AI代行堂を見る →

関連する巻物

この巻物、誰かのトークンも救えます

𝕏 で節約レシートをシェア