作業環境・自動化

Mac の Brave を Playwright から CDP で操作した話——セッション切れとの戦いに終止符を打つまで

Mac の Brave を Playwright から CDP で操作した話——セッション切れとの戦いに終止符を打つまで

この記事は約 8 分で読めます

📖 目次
  1. 📌 はじめに
  2. 📌 CDP 接続の仕組みをざっくり理解する
  3. 📌 Brave をデバッグモードで起動する
  4. 📌 cdp_browser.py を作った
  5. 📌 ハマったポイント3つ
  6. 📌 launchd に組み込んでいる
  7. 📌 現在の運用状況
  8. 📌 まとめ
  9. 📌 関連記事

最終更新: 2026-04-28

はじめに

Web自動化で一番時間を溶かしたのは、セッション切れだった。

note 自動投稿・BSky エンゲージ・Gemini Web 操作——この3本だけで、1週間に平均4〜5回は「ログインしてください」が出ていた。スクリプトを走らせる前にターミナルを確認して、ログインエラーを見て、手動でブラウザを開いて……その一連が毎朝の儀式になっていた時期がある。

最初は storage_state で対処しようとした。Playwright の公式アプローチで、ログイン済みのセッションをJSONに保存して使い回す方法だ。2週間は動いた。3週目に note のクッキー有効期限が切れて振り出し。Amazon は別のトークン体系で storage_state 自体が信頼できなかった。

で、私はこっちに倒した。日常使いしてる Brave ブラウザに CDP(Chrome DevTools Protocol)で接続して、そのセッションをそのまま流用する。

一回ログインしてしまえば、あとは自動化スクリプトが「すでにログイン済みのブラウザ」として動く。セッション切れが起きても Brave 上で手動ログインするだけで即復旧——これがめちゃくちゃ楽だった。

ただ、ここに辿り着くまでにそれなりにハマった。今日はその記録。


CDP 接続の仕組みをざっくり理解する

CDP は Chromium プロジェクトが提供するデバッグ用プロトコルで、外部からブラウザを操作できるようにする仕組み。本来は Chrome DevTools がブラウザと通信するために使っているもので、Chrome DevTools Protocol の仕様は公式で公開されている。

Playwright はこれを使って既存のブラウザプロセスに「接続」できる。新しくブラウザを起動するんじゃなくて、すでに動いているブラウザに後から乗り込む感じ。Playwright 公式ドキュメントの connect_over_cdp に詳細がある。

Brave は Chromium ベースなので CDP がそのまま使える。起動時に --remote-debugging-port=9222 を渡してやれば、localhost:9222 でデバッグポートが開く。


Brave をデバッグモードで起動する

まずここから。通常の起動方法だと CDP は有効にならないので、専用のシェルスクリプトを用意した。

[コード略 — 詳細は元記事参照]

これを実行して Brave が立ち上がったら、ブラウザ上で手動ログインを済ませておく。note・X・Amazon・Gemini Web など、スクリプトが操作したいサービスを全部片付ける。初回だけ10分ほどかかるが、以後は Brave を起動するだけでいい。

疎通確認はこれ一行でできる。

[コード略 — 詳細は元記事参照]

"Browser": "Brave/..." みたいなレスポンスが返ってきたら OK。ここで何も返ってこないか ConnectionRefusedError が出る場合は、Brave がデバッグポートなしで通常起動している。一度終了して上のスクリプトで再起動する。


cdp_browser.py を作った

プロジェクト内で現在5本のスクリプトが CDP 接続を使っている。最初は各スクリプトに接続コードを書いていたが、ポート番号や待機処理を何箇所も直すのが面倒になって、共通ライブラリとして切り出した。これが 01_Scripts/lib/cdp_browser.py

[コード略 — 詳細は元記事参照]

Python の asyncio を使った async 版も

同様に用意してある。connect_cdp_asyncopen_tab_async の2つ。BSky エンゲージは非同期で複数タブを並列操作するので、そちらを使っている。

使い方はシンプルで、各スクリプトでこう書くだけ。

[コード略 — 詳細は元記事参照]

browser.close() は CDP 接続を切るだけで Brave 本体は落ちない。これ、最初ちゃんと理解できていなかった。「スクリプトが終わるたびに Brave が落ちる気がする」と2日間悩んで、実は別の原因だったと気づいた。CDP 接続を閉じることとプロセスを終了することは完全に別の操作——腹落ちしてからは混乱がなくなった。


ハマったポイント3つ

1. contexts が空のときがある

Brave を起動したばかりで何もタブを開いていないと、browser.contexts が空のリストになることがある。contexts[0]IndexError: list index out of range が出て気づいた。

コード上は if browser.contexts else browser.new_context() でフォールバックしているが、実用上は Brave 起動後に少なくとも1タブ開いておく運用にしている。エラーで気づく前に「なぜか最初の1回だけ失敗する」という症状が3日続いていた。

2. ポート番号の競合

--remote-debugging-port=9222 は固定で使っているが、何かの拍子に Brave が落ちて再起動したとき、ゾンビプロセスがポートを掴んだままになることがあった。この状態だと Playwright 側が接続できず、エラーメッセージも「接続先がない」系で紛らわしい。原因特定だけで30分近くかかった。

[コード略 — 詳細は元記事参照]

で確認して、PID を kill してから再起動するのが手順として定着した。

3. browser.close() で Brave が落ちると思ってた

「スクリプト終了 → Brave が落ちた」という因果関係を疑い続けていた時期があった。実際に Brave が落ちていたのは、長時間デバッグポートを掴んだままにしていたため macOS がリソース回収したケースだった。CDP 接続を閉じるのとブラウザプロセスを終了するのは別の話——これをちゃんと理解できたのが大きかった。


launchd に組み込んでいる

自動化スクリプトは launchd で定期実行しているので、Brave の起動も launchd で管理するか迷ったけど、今は手動起動にしている。

理由は単純で、Brave は日常的に使うブラウザだから、Mac を起動したら普通に開く。launchd 経由で起動すると、Brave のプロファイルがどのユーザーセッションで起動するかで挙動が変わることがわかって、ログイン状態の管理が複雑になる。手動ログインのフローを残したほうが現実的だった。

スクリプト側は CDP が繋がらないときに「Brave がデバッグモードで起動していません」と Discord 通知を飛ばすようにしてある。通知が来たら Brave を再起動するだけ——月に2〜3回あるかないか、というペースに落ち着いている。

[コード略 — 詳細は元記事参照]

現在の運用状況

今は note 自動投稿・BSky エンゲージ・KDP 関連の Gemini Web 操作・Amazon の A+ コンテンツ確認——この4系統が全部この CDP 接続経由で動っている。セッション切れで詰まることがほぼなくなった。以前は週4〜5回あったログインエラーが、今は月2〜3回程度。

cdp_browser.py に集約してから、新しいスクリプトを書くときの実装コストもかなり下がった。接続部分を毎回書かなくていい。新しいサービスの自動化を追加するときも、ログイン済みの Brave で手動確認 → スクリプト化、という流れが確立している。


まとめ

CDP 接続は、ログイン状態を維持したいケースにかなり効く。新規ブラウザ起動 + storage_state の管理をやめてから、週4〜5回あった自動化のトラブルが月2〜3回まで落ちた。

Brave を --remote-debugging-port=9222 で起動 → 手動ログイン → cdp_browser.py 経由で接続。流れとしてはこれだけ。シンプルだけど、storage_state の落とし穴・ポート競合・browser.close() の誤解、この3つで結構な時間を溶かした。同じところで詰まっている人の参考になれば。✨


[コード略 — 詳細は元記事参照]

一ノ瀬泰斗のアバター
一ノ瀬泰斗
AI自動化エンジニア / Python個人開発者

Claude Code × Ollama × launchd で SNS・ブログ・KDPを全自動化。実測データと失敗談を軸に、月5万円収益化のリアルな記録を発信中。

💬 自動化の相談・小規模受託も受付中:「launchd で毎朝 AI が動く仕組みを作りたい」「KDP の自動出版を組みたい」など、X (@taito_automate) の DM からお気軽にどうぞ。


関連記事

✨ AUTHOR'S KDP BOOKS

かかる人向ケ、10分でわかるAI自動化入門

Claude Code / Ollama / launchd の実践テクニックをコンパクトにまとめたシリーズ。非エンジニアの会社員向けに書いてます。

Amazonで見る ›

✨ FOLLOW ME

AI自動化の実験・失敗・実測データを毎日発信中

𝕏 フォローする