Browser Use CLI 完全ガイド:Claude Codeと組み合わせるブラウザ自動操作

Browser Use CLI 完全ガイド:Claude Codeと組み合わせるブラウザ自動操作 AI開発

ブラウザ自動操作のフレームワークとしてBrowser Use(Python ライブラリ)は広く使われるようになりましたが、同梱されているBrowser Use CLIを使うとターミナルコマンドだけでブラウザを操作できます。Pythonコードを書かずにブラウザをコマンドで動かせるため、Claude Codeによる自動化スクリプト開発のデバッグに最適です。

CLIの特徴は名前付きセッションによる状態の永続化です。コマンド間でブラウザのセッションが引き継がれるため、「URLを開く→要素を確認→クリック→テキスト取得」という一連の流れをシェルスクリプトとして記述できます。また--headedオプションでブラウザウィンドウを表示しながら操作できるので、Claude Codeがスクリプトを生成している間にターミナルで動作確認するというワークフローが自然に成立します。

この記事では、Browser Use CLIの基本コマンドから実践的なユースケースまで、Claude Codeとの連携方法を中心に詳しく解説します。

この記事で学べること
・Browser Use CLIのセットアップと基本コマンド
・名前付きセッションを使ったマルチタブ並列操作
・–headedオプションでビジュアルデバッグする方法
・競合調査・Webモニタリング・ニュース収集の実践例
・Python Agent.run() とCLIコマンドの使い分け
スポンサーリンク

Python APIとCLIコマンド:何が違うのか

前回の記事ではBrowser UseのPython APIを中心に解説しました。CLIはそれと別のアプローチで、ターミナルコマンドで直接ブラウザを操作するツールです。

項目 Python API(Agent) CLIコマンド
操作方法 Pythonコードで記述 ターミナルコマンド
自律性 LLMが自律的に判断・操作 開発者がコマンドで明示的に操作
セッション管理 スクリプト内のみ 名前付きセッションで永続化
マルチタブ コードで実装 –sessionオプションで並列化
シェル統合 pipで呼び出しが必要 直接コマンドで統合しやすい
向いている用途 複雑な判断が必要な処理 定型的な操作・デバッグ・シェルスクリプト
CLIコマンドが特に輝く場面
・Claude Codeと並行してブラウザを手元で確認しながら開発するとき
・シェルスクリプトやcronジョブにブラウザ操作を組み込みたいとき
・複数のサイトを名前付きセッションで同時に処理したいとき

セットアップ

Python 3.11以上が必要です
Browser UseはPython 3.11+が必須です。python --versionで確認してください。
Terminal
# uvを使う場合(推奨)
uv tool install browser-use

# pipを使う場合
pip install browser-use

# ブラウザのインストール(初回のみ)
playwright install chromium

# インストールの確認
browser-use doctor

APIキーの設定

Terminal(macOS / Linux)
export ANTHROPIC_API_KEY="sk-ant-..."
# 永続化する場合は ~/.bashrc や ~/.zshrc に追記
Terminal(Windows)
set ANTHROPIC_API_KEY=sk-ant-...
# 永続化する場合はシステム環境変数に追加

基本コマンドリファレンス

Browser Use CLIのコマンドは「ナビゲーション」「状態確認」「操作」「データ取得」の4グループに整理できます。

ナビゲーション

Terminal
browser-use open https://example.com   # URLに移動
browser-use back                       # 前のページに戻る
browser-use scroll down                # 下にスクロール
browser-use scroll up                  # 上にスクロール

状態確認

Terminal
browser-use state          # 操作可能な要素をインデックス付きで一覧表示
browser-use screenshot     # スクリーンショットを保存
browser-use get title      # ページタイトルを取得
browser-use get html       # HTMLソース全体を取得
browser-use get text       # ページ内テキストを取得
browser-use get value <番号>   # 要素の値を取得
browser-use state が要となるコマンドです
このコマンドを実行すると、現在のページ上でクリック・入力できる要素が番号付きで表示されます。
例: [0] input "検索", [1] button "送信", [2] link "ログイン"
この番号を使って後続のコマンドで要素を指定します。インデックスはページが変わるたびにリセットされるため、操作の直前に必ず state を実行して番号を確認してください。

操作コマンド

Terminal
browser-use click <番号>              # 要素をクリック
browser-use type "テキスト"           # フォーカス中の要素にテキスト入力
browser-use input <番号> "テキスト"   # 要素をクリックしてテキスト入力
browser-use keys "Enter"              # キーボードキーを送信
browser-use select <番号> "選択肢"    # セレクトボックスから選択
browser-use hover <番号>              # 要素にホバー
browser-use upload <番号> "/path"     # ファイルをアップロード
browser-use dblclick <番号>           # ダブルクリック

高度なコマンド

Terminal
# JavaScriptを実行(戻り値を取得できる)
browser-use eval "document.title"
browser-use eval "document.querySelectorAll('.item').length"

# Pythonコードをローカルで実行(変数が永続化される)
browser-use python "import json; data = {'key': 'value'}"

# 要素の出現・テキストを待機
browser-use wait selector ".loaded"
browser-use wait text "完了しました"

# タブ操作
browser-use switch <タブ番号>
browser-use close-tab

グローバルオプション

オプション 説明
--headed ブラウザウィンドウを表示 browser-use --headed open URL
--session NAME 名前付きセッションを使用 browser-use --session work open URL
--json 結果をJSON形式で出力 browser-use --json get text
--profile NAME Chromeプロファイルを使用 browser-use --profile Default open URL
--cdp-url URL CDP経由でChromeに接続 browser-use --cdp-url ws://... open URL

実践:フォーム入力のサンプル

Terminal(フォーム入力の流れ)
# ① ページを開く
browser-use open https://example.com/contact

# ② 操作可能な要素を確認
browser-use state
# 出力例: [0] input "お名前", [1] input "メールアドレス", [2] button "送信"

# ③ フォームに入力
browser-use input 0 "山田 太郎"
browser-use input 1 "yamada@example.com"

# ④ 送信して確認
browser-use click 2
browser-use screenshot confirm.png

–headed オプション:ビジュアルデバッグ

スクリプト開発時に最も役立つのが --headed オプションです。ブラウザウィンドウを表示した状態でコマンドを実行できるため、Claude Codeがスクリプトを生成している横のターミナルで動作確認しながら開発を進められます。

Terminal
# ブラウザウィンドウを表示しながら操作
browser-use --headed open https://example.com
browser-use --headed state

# セッションと組み合わせてウィンドウを開いたまま複数コマンド実行
browser-use --headed --session debug open https://example.com
browser-use --session debug state    # --headedなしでも同じセッションに接続
browser-use --session debug click 0
ターミナル1(Claude Code) ターミナル2(デバッグ)
自動化スクリプトを作成中 browser-use --headed --session debug open URL
「このボタンを押すには?」 browser-use --session debug state でインデックス確認
インデックスをスクリプトに組み込む ウィンドウを見ながら click を試す
エラー箇所を特定 browser-use --session debug screenshot debug.png
–headedデバッグが特に有効な場面
・ページ構造が複雑でセレクタの特定が難しいとき
・ログインが必要なサイトのフロー確認
・SPAや動的コンテンツが多いページのタイミング確認
・初めて触るサービスの操作手順を探索するとき

名前付きセッション:マルチタブ並列操作

CLI の特徴的な機能が名前付きセッションです。--sessionオプションで複数のブラウザセッションを独立して管理でき、並列処理が可能になります。

Terminal
# セッション "research" を開始してサイトAに移動
browser-use --session research open https://siteA.com
browser-use --session research state

# 別セッション "monitor" を同時に使用
browser-use --session monitor open https://statuspage.io
browser-use --session monitor get text

# 2つのセッションは独立しており互いに影響しない
browser-use --session research click 3
browser-use --session monitor screenshot monitor.png

# アクティブなセッション一覧を確認
browser-use sessions

# セッションを終了
browser-use close --session research
# または全セッション終了
browser-use close --all
名前付きセッションの仕組み
セッションごとに独立したブラウザコンテキストが管理されます。同じセッション名を使えばコマンド間でブラウザの状態が引き継がれます。環境変数 BROWSER_USE_SESSION にデフォルトのセッション名を設定することもできます。

実践ユースケース

競合サイトの価格調査

複数サイトの価格情報を定期的に収集するシェルスクリプトです。--jsonで構造化出力し、jqで整形して保存します。

price_monitor.sh
#!/bin/bash
# 競合3サイトの価格を収集

DATE=$(date +%Y-%m-%d)
OUTPUT_DIR="./price_data"
mkdir -p "$OUTPUT_DIR"

for SITE in "siteA.com" "siteB.com" "siteC.com"; do
  echo "=== $SITE の価格を取得中 ==="
  SESSION="price_${SITE//./_}"

  # ページを開いて価格テーブルをスクレイピング
  browser-use --session "$SESSION" open "https://$SITE/products"
  browser-use --session "$SESSION" wait selector ".product-grid"

  # テキストをJSON形式で取得してファイルに保存
  browser-use --session "$SESSION" --json get text     > "${OUTPUT_DIR}/${SITE}_${DATE}.json"

  browser-use close --session "$SESSION"
  echo "$SITE 完了"
  sleep 3  # サーバー負荷軽減のため待機
done

echo "全サイトの収集が完了しました。"

Python Agentと組み合わせた高度な価格分析

CLIでデータを収集し、Python AgentでAI分析するパターンです。

price_analysis.py
#!/usr/bin/env python3
"""CLIで収集したデータをPython Agentで分析"""
import subprocess, json, asyncio
from browser_use import Agent
from langchain_anthropic import ChatAnthropic

def cli_get_page_text(url: str) -> str:
    """CLIコマンドで指定URLのテキストを取得"""
    subprocess.run(["browser-use", "open", url], capture_output=True)
    result = subprocess.run(
        ["browser-use", "--json", "get", "text"],
        capture_output=True, text=True
    )
    return result.stdout

async def analyze_prices(raw_data: str) -> dict:
    """Python AgentでAI分析(CLIでは難しい判断処理を担当)"""
    llm = ChatAnthropic(model="claude-sonnet-4-6")
    agent = Agent(
        task=f"以下のテキストから製品名と価格を抽出してJSON形式で返してください。

{raw_data[:3000]}",
        llm=llm,
    )
    result = await agent.run()
    return result.final_result()

if __name__ == "__main__":
    # CLI で取得 → Agent で解析
    raw = cli_get_page_text("https://example.com/products")
    analysis = asyncio.run(analyze_prices(raw))
    print(json.dumps(analysis, ensure_ascii=False, indent=2))

サービスステータス監視

ステータスページを定期チェックして異常があれば通知するスクリプトです。

status_monitor.sh
#!/bin/bash
# サービスステータス監視(cronで毎時実行)

SERVICES=(
  "https://status.example.com"
  "https://app.example.com/health"
)
LOG_FILE="./status_$(date +%Y%m%d).log"
SLACK_WEBHOOK="https://hooks.slack.com/services/xxx"

for URL in "${SERVICES[@]}"; do
  SESSION="monitor_$(echo $URL | md5sum | cut -c1-8)"

  browser-use --session "$SESSION" open "$URL"
  browser-use --session "$SESSION" wait selector "body"

  STATUS=$(browser-use --session "$SESSION" --json get text)
  TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")

  # ログに記録
  echo "$TIMESTAMP | $URL | $STATUS" >> "$LOG_FILE"

  # 「degraded」「down」「障害」が含まれていれば Slack 通知
  if echo "$STATUS" | grep -qi "degraded\|down\|障害\|停止"; then
    curl -s -X POST "$SLACK_WEBHOOK"       -H "Content-Type: application/json"       -d "{"text":"⚠️ $URL で異常を検出"}"
  fi

  browser-use close --session "$SESSION"
done

ニュース収集パイプライン(SQLite保存)

テックニュースサイトから記事を自動収集してSQLiteに蓄積するパイプラインです。CLIでページテキストを取得し、Pythonで構造化して保存します。

news_pipeline.py
#!/usr/bin/env python3
"""テックニュース収集パイプライン(CLI + Python処理)"""
import subprocess, json, sqlite3, asyncio
from datetime import datetime
from browser_use import Agent
from langchain_anthropic import ChatAnthropic

SOURCES = {
    "hacker_news": "https://news.ycombinator.com",
    "lobsters":    "https://lobste.rs",
}

def fetch_page_text(url: str) -> str:
    """Browser Use CLIでページのテキストを取得"""
    subprocess.run(["browser-use", "open", url],
                   capture_output=True, text=True)
    # 動的コンテンツの読み込みを待機
    subprocess.run(["browser-use", "wait", "selector", "body"],
                   capture_output=True, text=True)
    result = subprocess.run(
        ["browser-use", "--json", "get", "text"],
        capture_output=True, text=True
    )
    return result.stdout

async def extract_articles(raw_text: str, source: str) -> list:
    """Python AgentでLLMが記事情報を抽出"""
    llm = ChatAnthropic(model="claude-sonnet-4-6")
    agent = Agent(
        task=(
            f"以下は{source}のページテキストです。"
            "記事のタイトル・URL・スコアを抽出してJSON配列で返してください(最大20件)。

"
            + raw_text[:4000]
        ),
        llm=llm,
    )
    result = await agent.run()
    try:
        return json.loads(result.final_result()) if result.final_result() else []
    except json.JSONDecodeError:
        return []

def save_articles(db_path: str, source: str, articles: list) -> int:
    """SQLiteに保存(重複はスキップ)"""
    db = sqlite3.connect(db_path)
    cur = db.cursor()
    cur.execute("""
        CREATE TABLE IF NOT EXISTS articles (
            id INTEGER PRIMARY KEY, source TEXT,
            title TEXT UNIQUE, url TEXT, score TEXT,
            scraped_at TEXT
        )
    """)
    saved = 0
    for a in articles:
        try:
            cur.execute(
                "INSERT OR IGNORE INTO articles VALUES (NULL,?,?,?,?,?)",
                (source, a.get("title"), a.get("url"),
                 str(a.get("score","")), datetime.now().isoformat())
            )
            if cur.rowcount: saved += 1
        except Exception: pass
    db.commit(); db.close()
    return saved

if __name__ == "__main__":
    DB = "tech_news.db"
    for name, url in SOURCES.items():
        print(f"収集中: {name}")
        raw = fetch_page_text(url)
        articles = asyncio.run(extract_articles(raw, name))
        n = save_articles(DB, name, articles)
        print(f"  → {n}件を新規保存")

    # 集計表示
    db = sqlite3.connect(DB)
    cur = db.cursor()
    cur.execute(
        "SELECT source, COUNT(*) FROM articles "
        "WHERE scraped_at > datetime('now','-24 hours') GROUP BY source"
    )
    print("
[24時間以内の収集状況]")
    for src, cnt in cur.fetchall():
        print(f"  {src}: {cnt}件")
    db.close()

Claude Code Skillsとして組み込む

Claude Code Skillsとして登録することで、Claude Codeの会話からBrowser Use CLIを呼び出せるようになります。

browser_cli_skill.py(Skillとして登録)
#!/usr/bin/env python3
"""
Claude Code Skill: Browser Use CLI ラッパー
使い方:
  python browser_cli_skill.py open https://example.com
  python browser_cli_skill.py state
  python browser_cli_skill.py click 0
  python browser_cli_skill.py eval "document.title"
"""
import sys, json, subprocess

def run_browser_cmd(args: list[str], json_output: bool = False) -> dict:
    """browser-useコマンドを実行して結果を返す"""
    cmd = ["browser-use"]
    if json_output:
        cmd.append("--json")
    cmd.extend(args)

    result = subprocess.run(cmd, capture_output=True, text=True, encoding="utf-8")
    return {
        "stdout": result.stdout.strip(),
        "returncode": result.returncode,
        "stderr": result.stderr.strip() if result.returncode != 0 else "",
    }

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("Usage: python browser_cli_skill.py <command> [args...]")
        sys.exit(1)

    command = sys.argv[1]
    args = sys.argv[2:]

    # get系コマンドはJSON出力
    use_json = command in ("get", "state", "eval")
    result = run_browser_cmd([command] + args, json_output=use_json)
    print(json.dumps(result, ensure_ascii=False, indent=2))

Python AgentとCLIコマンドの使い分け

「どちらを使うべきか」の判断基準をまとめます。基本的に「判断が必要なら Agent、定型処理ならCLI」と覚えておくと迷いません。Python AgentのAPIについてはClaude Agent SDK ガイドも参照してください。

シナリオ 推奨 理由
シェルスクリプトへの組み込み CLIコマンド コマンド1行で記述できる
cronジョブによる定期実行 CLIコマンド セッション永続化で安定動作
Claude Codeでのデバッグ CLI(–headed) ウィンドウを見ながら確認できる
複数サイトの並列処理 CLI(名前付きセッション) –sessionで独立管理
複雑な条件分岐ロジック Python Agent LLMが状況を判断して操作
UIが頻繁に変わるサイト Python Agent AIがセレクタ変更に自動適応
構造化データの抽出 CLI取得 + Agent解析 取得は高速CLI・解析はAI

トラブルシューティング

ブラウザが起動しない

Terminal
# まず診断コマンドを実行
browser-use doctor

# Chromiumを再インストール
playwright install chromium

# 既存のChromeプロファイルを使う
browser-use --profile "Default" open https://example.com

# リモートのCDPに接続
browser-use --cdp-url ws://localhost:9222 open https://example.com

セッションが応答しない

Terminal
# アクティブなセッションを確認
browser-use sessions

# 全セッションを強制終了して再起動
browser-use close --all
browser-use open https://example.com

要素が見つからない(インデックスがずれる)

Terminal
# 毎回 state で最新インデックスを取得してから click する
browser-use state          # 必ず直前に実行
browser-use click 5        # 確認した番号を使う

# 動的コンテンツはセレクタ待機を入れる
browser-use wait selector ".product-list"
browser-use state          # 待機後に再取得

# JavaScriptで直接セレクタを指定する
browser-use eval "document.querySelector('[data-id="submit"]').click()"
インデックスはページ状態によって変わります
browser-use state で取得した番号はページの再読み込みや動的コンテンツの更新があるとずれます。操作の直前に必ず state を実行して番号を確認してください。

よくある質問

Qbrowser-use CLIとPython ライブラリは同時にインストールできますか?

Aはい。pip install browser-use で両方が使えるようになります。CLIコマンド(browser-use open等)とPython API(from browser_use import Agent)は同じパッケージに含まれており、用途に応じて使い分けることができます。

Q名前付きセッションはいつ終了しますか?

Aセッションは browser-use close --session 名前 で明示的に終了するか、browser-use close --all で全セッションを一括終了できます。システムを再起動した場合もセッションはリセットされます。

Qログインが必要なサイトはどう扱えばよいですか?

A--profile "Default" オプションで既存のChromeプロファイルを使うと、ブラウザに保存されたログイン情報をそのまま使用できます。またはCDPで既に起動中のChromeに接続して(--cdp-url)、ログイン済みのブラウザを操作することも可能です。

Q大量のページを処理する場合に注意することは?

Aセッションを使い終わったら close コマンドで必ず終了してください。セッションを開きっぱなしにするとメモリ消費が増えます。また並列処理の際はサーバーへの礼儀として sleep コマンドで待機時間を設けることを推奨します。

Q–json オプションを使ってもJSONが返ってこない場合の対処法は?

Aまず browser-use doctor で環境を確認してください。コマンドが失敗している場合は標準エラー出力にエラーが出ているため、シェルスクリプト内では 2>&1 でエラーをキャッチして診断するのが有効です。

まとめ

Browser Use CLIはコマンドラインからブラウザを直接操作できるツールで、Claude Codeとの組み合わせで大きな力を発揮します。

機能 ポイント
browser-use state 要素を番号付きで確認、操作の起点となるコマンド
–headed オプション ブラウザ表示でリアルタイムデバッグ
名前付きセッション 複数サイトをマルチタブで並列処理
–json オプション 取得データをJSON形式でシェルに渡せる
eval / wait コマンド 動的コンテンツへの柔軟な対応

定型的な操作はCLIコマンドで高速処理し、判断が必要な処理はPython Agentに委ねるハイブリッドなアプローチが実務での最適解です。シェルスクリプトとの組み合わせや、cronジョブへの組み込みにも積極的に活用してみてください。

Browser UseのPython APIとPlaywrightを組み合わせたハイブリッドアプローチについては、PlaywrightとBrowser Useのブラウザ自動操作ガイドもあわせてご覧ください。