最終更新: 2026-04-28
同じことができるのに、なぜ2つあるのか
SNS自動化のパイプラインを組んでいると、ブラウザ操作が必ずどこかに挟まってくる。 Brave CDP 移行による実装トラブルの解決事例X(Twitter)への投稿、note のコメント返信、Gemini Web で画像を生成して保存する処理——全部ブラウザが要る。
手元にある選択肢は2つだった。Claude Code の Computer Use と、Python の Playwright。最初は「どちらか一方に統一した方がシンプルでいい」と思っていた。実際に両方を本番で動かし続けて、気づいたら使い分けが自然に決まっていた。最終的に同じ処理を4回書き直すことになったので、その経緯を整理しておく。
Claude Code(Computer Use)が向いている場面
Computer Use の強みは「セレクタがなくても動く」ことだ。画面のスクリーンショットを撮って、Claude が「ここにテキストフィールドがある」と判断して操作する。DOM の構造を知らなくていい。
私が実際に使っているのは Gemini Web での画像生成操作。Gemini は UI の更新が頻繁で、固定セレクタで書いたスクリプトが2週間で壊れた経験がある。button[data-testid="send-button"] を指定していたら、ある朝突然 data-testid が消えていて、スクリプトがエラーログを吐いて静止した——という事件が2回起きた。それ以降、Gemini 操作だけ Computer Use に切り替えた。
# Claude Code の Computer Use 経由で Gemini を操作するイメージ
# ANTHROPIC_API_KEY は env から除外して渡す(子プロセスへの漏洩防止)
env = {k: v for k, v in os.environ.items() if k != "ANTHROPIC_API_KEY"}
result = subprocess.run(
["claude", "-p", f"Gemini Webを開いて「{prompt}」で画像を生成して保存して"],
env=env,
capture_output=True,
text=True,
timeout=120
)
ただし、遅い。1回の操作に30〜90秒かかる。スクリーンショット → Claude が解釈 → アクションを決定 → 実行、このループを複数回回すから当然そうなる。launchd で1時間おきに叩く処理には向かない——コストも積み上がる一方だ。
Playwright が向いている場面
Playwright は「同じ操作を何百回でも安定して繰り返す」ことに向いている。セレクタが確定していれば、1回の操作が0.5〜3秒で終わる。
今のパイプラインでは、note のコメント自動返信と X への投稿で使っている。
# note_comment_reply.py の一部
async def reply_to_comment(page, comment_url, reply_text):
await page.goto(comment_url)
await page.wait_for_selector(".commentForm textarea", timeout=10000)
await page.fill(".commentForm textarea", reply_text)
await page.click(".commentForm button[type='submit']")
await page.wait_for_load_state("networkidle")
このスクリプトは engage_launcher.sh から1時間おきに起動する。1回の実行で5件処理して終了——ヘッドレスで動くので、MacBook が別の作業をしていても邪魔にならない。
ただ、セレクタが壊れたら即死する。note が UI を更新した直後にセレクタが変わって、TimeoutError: Timeout 10000ms exceeded が延々とログに積まれた状態で2日間気づかなかった、という失敗がある。エラーを Discord に通知する仕組みを作るまでは、投稿が止まっていても気づけなかった。壊れること自体は許容できる。気づかないことが問題だった。
3段階フォールバックという折衷案
X のモニタリングスクリプト(x_monitor_claudeai.py)では、両方の良いところを組み合わせる構成を試した。API が使えるなら API、壊れていれば Playwright、それも死んでいればモックデータ——という順序で試みる。
async def fetch_tweets(self):
# 1段階目: X API v2(Bearer Token があれば)
if self.bearer_token and self.bearer_token != "your_bearer_token_here":
tweets = await self._fetch_via_api()
if tweets:
return tweets
# 2段階目: Playwright スクレイピング
tweets = await self._fetch_via_playwright()
if tweets:
return tweets
# 3段階目: モックデータ(開発・テスト用)
return self._get_mock_tweets()
X API は有料プランが必要で、まだ Bearer Token を取得していない。なので現状はほぼ Playwright の段階で処理が止まっている。フォールバック構成の良さは「どれかが動けば止まらない」という余裕が生まれること。API の利用規約が変わっても、Playwright が生きていればパイプラインは続く。
実測で見えた差
2週間ほど両方を本番で動かして計測した。速度の差は予想以上だった。Computer Use は1操作30〜90秒、Playwright は0.5〜3秒。単純計算で10倍以上違う。
ただ、安定性の評価は逆転した。Playwright はセレクタが変わると即死するが、Computer Use は多少の見た目の変化には耐える。Gemini のボタンデザインが変わっても、Computer Use は「送信ボタンらしいもの」を画面から探して押し続けた——これが地味に助かった。
処理 | Computer Use | Playwright
---------|-------------|------------
速度 | 30〜90秒 | 0.5〜3秒
安定性 | UI変更に強い | セレクタ依存
コスト | 高(トークン)| 低(ほぼ無料)
初期実装 | 速い | セレクタ調査が必要
コストについては、Computer Use で1操作ごとにスクリーンショットを3〜5枚撮る。Claude Sonnet 4.6 の画像トークンが積み上がるので、頻繁に叩く処理に使うと月単位で数千円の差になる。
今の構成でどう使い分けているか
今は「1日に何回呼ばれるか」を最初に確認する。launchd で1時間おきに動くなら Playwright 一択だ。Computer Use をそこに使ったら費用対効果が崩壊する。
次に「対象サービスの UI がどれだけ変わりやすいか」を見る。Gemini のような更新頻度が高いサービスは Computer Use に振る。note や X はセレクタが比較的安定しているので Playwright で書く——という判断を今はしている。
あと、プロトタイプ段階では Computer Use から始める、というのが思ったより合理的だった。「どこをクリックすれば動くか」をセレクタで調べる時間を省けるので、動作確認が速い。動くことを確認してから、必要に応じて Playwright で書き直す。最初にこの順序でやっていれば、書き直し4回が2回で済んだかもしれない。
まとめ
頻度が高い・速度がいる・コストを抑えたい → Playwright。UI が複雑・セレクタが不明・更新頻度が高いサービス → Computer Use。
迷ったら Playwright で試して、壊れるようなら Computer Use に切り替える——というのが私の現実解になっている。
今のパイプラインは Playwright がメインで、Computer Use は Gemini Web 操作だけ。この構成に落ち着くまでに3〜4回書き直した。試して壊して、また直す。それしかない。✨