Claude Codeを使った開発の中で、「Webページの情報を自動で取得したい」「ブラウザ操作を自動化して作業を効率化したい」というニーズは日常的に発生します。そのような場面で強力な選択肢となるのが、PlaywrightとBrowser Useの2つのツールです。
Playwrightは従来型の確定的なブラウザ自動化ライブラリです。セレクタを明示的に指定してDOMを操作するため、動作が安定しており高速です。一方、Browser UseはLLMを活用したAIエージェント型のブラウザ操作ライブラリで、自然言語でタスクを指示するだけで、AIが自律的にページを解析しながら操作を進めます。
この記事では、PlaywrightとBrowser UseをClaude Codeと連携させる方法を、実際のコード例と合わせて詳しく解説します。それぞれの特性と使い分けを理解することで、ブラウザ自動操作の効率を大幅に高めることができます。
・PlaywrightとBrowser Useの根本的な違い
・Claude Codeとの連携方法(MCP・CLI・Skills)
・トークン効率の比較と節約テクニック
・どちらを使うべきかの判断フロー
・両者を組み合わせたハイブリッドアプローチの実装
PlaywrightとBrowser Use:根本的な違い
2つのツールは「ブラウザを操作する」という目的は同じですが、アーキテクチャが根本的に異なります。
| 項目 | Playwright | Browser Use |
|---|---|---|
| 操作モデル | 命令型(セレクタ指定) | エージェント型(自然言語指示) |
| DOM知識 | 開発者が構造を知る必要あり | AIがページを解析して判断 |
| UI変更への耐性 | セレクタ変更でスクリプト破綻 | 自動的に適応 |
| 実行速度 | 高速(1〜3秒/ページ) | 中速(2〜8秒/ページ) |
| 成功率の目安 | 既知ページで100% | 未知ページで70〜85%程度 |
| LLMトークンコスト | なし(AI不使用) | タスクに応じて変動 |
| 主な用途 | テスト自動化・定型処理 | 探索的作業・変動するUI |
UIが安定していて処理が定型的 → Playwright
UIが変動する・探索的なタスク → Browser Use
両方が必要な複雑な処理 → ハイブリッドアプローチ
Playwrightのセットアップと基本操作
インストール
pip install playwright playwright install # Chromium / Firefox / WebKit をダウンロード playwright install chromium # Chromium のみの場合
基本的な同期APIの使い方
Playwrightには同期API(sync_api)と非同期API(async_api)の2種類があります。スクリプトで手軽に使うなら同期APIが便利です。
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
# ページに移動
page.goto("https://example.com")
# テキスト入力
page.fill('input[name="q"]', "Python playwright")
# クリック
page.click('button[type="submit"]')
# ページ遷移を待機
page.wait_for_url("**/search**")
# テキスト取得(inner_text: 表示されている文字のみ)
title = page.title()
print(f"ページタイトル: {title}")
# スクリーンショット保存
page.screenshot(path="result.png")
browser.close()
inner_text(): CSSで非表示の要素を除いた、実際に表示されているテキストを取得します。text_content(): 非表示要素も含めた全テキストを取得します。スクレイピングでは通常
inner_text() を使うのが自然な結果を得やすいです。よく使うメソッド一覧
| メソッド | 用途 | 例 |
|---|---|---|
goto(url) |
URLに移動 | page.goto("https://example.com") |
fill(selector, value) |
テキスト入力 | page.fill("input#email", "test@example.com") |
click(selector) |
要素をクリック | page.click("button[type=submit]") |
get_by_role(role) |
セマンティック選択 | page.get_by_role("button", name="送信").click() |
wait_for_selector() |
要素の出現待機 | page.wait_for_selector(".loaded") |
query_selector_all() |
複数要素取得 | page.query_selector_all("li.item") |
inner_text() |
表示テキスト取得 | el.inner_text() |
screenshot() |
スクリーンショット | page.screenshot(path="out.png") |
非同期APIによる並列処理
複数ページを同時に処理する場合は非同期APIが有効です。処理速度を大幅に向上させることができます。
import asyncio
from playwright.async_api import async_playwright
async def scrape_page(browser, url):
page = await browser.new_page()
await page.goto(url)
title = await page.title()
await page.close()
return title
async def main():
async with async_playwright() as p:
browser = await p.chromium.launch()
# 3ページを並列処理
urls = [
"https://example.com/page1",
"https://example.com/page2",
"https://example.com/page3",
]
tasks = [scrape_page(browser, url) for url in urls]
titles = await asyncio.gather(*tasks)
for url, title in zip(urls, titles):
print(f"{url}: {title}")
await browser.close()
asyncio.run(main())
Browser Useのセットアップと基本操作
Browser UseはPlaywrightをベースに、LLMによる自律的な意思決定を組み合わせたライブラリです。高レベルのタスク(「GitHubでbrowser-useのスター数を調べて」など)を自然言語で指示するだけで、AIがページを解析しながら操作を進めます。
インストール
Browser UseはPython 3.11+を必須としています。
python --version で事前に確認してください。# uvを使う場合(推奨) uv add browser-use langchain-anthropic # browser-use + Claude用LangChainアダプタ # pipを使う場合 pip install browser-use langchain-anthropic playwright install # ブラウザのインストール(browser-use内部でPlaywrightを使用)
Browser UseでClaudeを使うには環境変数
ANTHROPIC_API_KEY を設定してください。export ANTHROPIC_API_KEY="sk-ant-..."(macOS/Linux)set ANTHROPIC_API_KEY=sk-ant-...(Windows)基本的なエージェントの使い方
import asyncio
from browser_use import Agent
from langchain_anthropic import ChatAnthropic
async def main():
# langchain_anthropic の ChatAnthropic でClaudeを指定
llm = ChatAnthropic(model="claude-sonnet-4-6")
agent = Agent(
task="GitHubでbrowser-useリポジトリのスター数を調べてください",
llm=llm,
)
# エージェントを実行(自律的にブラウザを操作して結果を返す)
result = await agent.run()
print(result.final_result())
asyncio.run(main())
コード内でタスクを自然言語で記述するだけで、エージェントが自律的にブラウザを操作して結果を返します。セレクタやDOM構造の知識は一切不要です。
カスタムアクションの追加
Browser UseのControllerを使うと、独自のアクションをエージェントに追加してドメイン固有の処理を組み込めます。
import asyncio
from browser_use import Agent, Controller
from langchain_anthropic import ChatAnthropic
# カスタムアクションを登録するコントローラー
controller = Controller()
@controller.action("現在のページからすべての価格情報を抽出する")
async def extract_prices(browser) -> list:
"""テーブルの価格データを構造化して返す"""
page = await browser.get_current_page()
rows = await page.query_selector_all("table tbody tr")
prices = []
for row in rows:
cells = await row.query_selector_all("td")
if len(cells) >= 2:
name = await cells[0].inner_text()
price = await cells[1].inner_text()
prices.append({"プラン": name.strip(), "価格": price.strip()})
return prices
async def main():
llm = ChatAnthropic(model="claude-sonnet-4-6")
agent = Agent(
task="料金ページを開いて全プランの価格を抽出してください",
llm=llm,
controller=controller, # カスタムアクションを渡す
)
result = await agent.run()
print(result.final_result())
asyncio.run(main())
・
@controller.action("説明") デコレータでエージェントに利用可能なアクションとして登録します・アクションの説明文はLLMが「いつ呼ぶべきか」を判断する材料になるため、具体的に書きましょう
・
browser 引数でPlaywrightのページオブジェクトにアクセスできます・返り値はそのままエージェントの結果として使用されます
Claude Codeとの連携:3つのアプローチ
PlaywrightをClaude Codeで使う方法は主に3つあります。それぞれトークン効率と柔軟性のトレードオフが異なります。Claude Code MCPガイドも参考にしてください。
① MCPサーバー経由(手軽だがトークン消費が多い)
# Playwright MCPサーバーをClaude Codeに登録 claude mcp add playwright npx @playwright/mcp@latest # プロジェクトスコープで登録する場合 claude mcp add playwright npx @playwright/mcp@latest --scope project
MCP経由では、アクセシビリティツリーやスクリーンショットがコンテキストに流れ込みます。手軽に使える反面、複数回操作するとコストが急増するため、試作段階での利用が向いています。
② CLIアプローチ(トークン効率が高い)
npm install -g @playwright/cli@latest playwright install
CLI経由では結果がファイルとして保存され、コンテキストに直接流れません。MCP比でトークン消費を大幅に削減できるため、繰り返し利用する場面に適しています。
③ Pythonスクリプト + Skills(最も効率的)
Pythonスクリプトとして実装し、Claude Code Skillsとして登録するのが最も柔軟で効率的なアプローチです。スクリプトの実行結果はファイル経由で受け取るため、トークン消費を最小化できます。
#!/usr/bin/env python3
"""
Claude Code Skill: ブラウザ自動操作
使い方: python browser_skill.py <url> <action>
action: title | screenshot | html
"""
import sys, json, asyncio
from playwright.async_api import async_playwright
async def execute(url: str, action: str) -> dict:
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
page = await browser.new_page()
await page.goto(url, wait_until="domcontentloaded")
result = {}
if action == "screenshot":
await page.screenshot(path="/tmp/screenshot.png")
result = {"file": "/tmp/screenshot.png"}
elif action == "title":
result = {"title": await page.title()}
elif action == "html":
with open("/tmp/page.html", "w", encoding="utf-8") as f:
f.write(await page.content())
result = {"file": "/tmp/page.html"}
await browser.close()
return result
if __name__ == "__main__":
url = sys.argv[1] if len(sys.argv) > 1 else "https://example.com"
action = sys.argv[2] if len(sys.argv) > 2 else "title"
print(json.dumps(asyncio.run(execute(url, action)), ensure_ascii=False))
| アプローチ | トークン消費目安 | 柔軟性 | セットアップ | 推奨場面 |
|---|---|---|---|---|
| MCPサーバー | 大(要注意) | 高 | 1コマンド | 手軽に試したいとき |
| CLI | 中(MCPの1/4程度) | 中 | npm install | 定型的な操作 |
| Skills | 最小(ファイル読取のみ) | 最高 | スクリプト作成 | 本番利用・繰り返し処理 |
トークン効率の実態と節約テクニック
Claude Codeでブラウザ自動操作を行う際、トークン消費は無視できないコスト要因です。アプローチによって消費量が大きく変わります。Claude Codeのコスト管理についても合わせて確認しておくと良いでしょう。
| シナリオ | Playwright MCP | Playwright CLI | Browser Use |
|---|---|---|---|
| 1ページ処理 ※ | 約114,000トークン | 約27,000トークン | 約40,000トークン |
| 10ページ連続処理 ※ | 約1,140,000トークン | 約270,000トークン | 約400,000トークン |
| 複雑な探索タスク ※ | 約200,000トークン | 約45,000トークン | 約60,000トークン |
※ トークン数はページの複雑さ・使用モデル・ブラウザの描画状況により変動します。上記は標準的なWebページを操作した際の参考値です。
① MCPよりCLI/Skillsを使う(大幅削減)
② スクリーンショットは必要な場合のみ有効化
③ 結果はファイル保存してパスだけコンテキストに渡す
④ 複数操作をバッチ化して1リクエストにまとめる
どちらを使うべき?判断フロー
PlaywrightとBrowser Useを使い分けるには、以下の観点で判断します。
| チェック項目 | Yes → 選択 | No → 選択 |
|---|---|---|
| 操作対象のDOMセレクタを把握している | Playwright | Browser Use |
| 同じ処理を繰り返し実行する | Playwright | どちらでも |
| UIが頻繁に変わる | Browser Use | Playwright |
| 複数サイトをまたぐ比較作業 | Browser Use | Playwright |
| 処理をテストとして再利用したい | Playwright | Browser Use |
| 自然言語でタスクを定義したい | Browser Use | Playwright |
「何をクリックすればいいか分かっている」→ Playwright
「ページを見ながら判断が必要」→ Browser Use
「定型80% + 判断20%」→ ハイブリッドアプローチ
ハイブリッドアプローチの実装
実務では「安定している部分はPlaywrightで高速処理し、不確実な部分だけBrowser Useで柔軟に対応する」ハイブリッドアプローチが最も効果的です。
import asyncio
from playwright.async_api import async_playwright
from browser_use import Agent
from langchain_anthropic import ChatAnthropic
async def scrape_product_page(url: str) -> dict:
"""
ハイブリッドアプローチ:
- Playwright: ナビゲーション・既知の構造を高速処理
- Browser Use: 未知のレイアウト・複雑な判断が必要な処理
"""
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
page = await browser.new_page()
await page.goto(url, wait_until="domcontentloaded")
# ①まず標準的な構造か確認(Playwrightで高速チェック)
standard_grid = await page.query_selector(".product-grid")
if standard_grid:
# ②標準レイアウトならPlaywrightで確定的に抽出
items = await page.query_selector_all(".product-item")
results = []
for item in items:
name_el = await item.query_selector(".product-name")
price_el = await item.query_selector(".product-price")
results.append({
"name": await name_el.inner_text() if name_el else "",
"price": await price_el.inner_text() if price_el else "",
})
await browser.close()
return {"method": "playwright", "data": results}
# ③非標準レイアウトはBrowser Useにフォールバック
await browser.close()
llm = ChatAnthropic(model="claude-sonnet-4-6")
agent = Agent(
task=f"{url} の全商品名と価格を抽出してJSON形式で返してください",
llm=llm,
)
result = await agent.run()
return {"method": "browser_use", "data": result.final_result()}
async def main():
url = "https://example.com/products"
result = await scrape_product_page(url)
print(f"使用ツール: {result['method']}")
print(f"取得データ: {result['data']}")
asyncio.run(main())
並列処理によるスループット向上
大量のページを処理する場合は、Playwrightの並列処理と組み合わせることでスループットを最大化できます。セマフォで同時実行数を制限することで、サーバーへの負荷を適切にコントロールできます。
import asyncio, json
from playwright.async_api import async_playwright
async def process_url(semaphore, browser, url):
"""セマフォで同時実行数を制限しながら並列処理"""
async with semaphore:
page = await browser.new_page()
try:
await page.goto(url, wait_until="domcontentloaded", timeout=15000)
title = await page.title()
return {"url": url, "title": title, "status": "ok"}
except Exception as e:
return {"url": url, "error": str(e), "status": "error"}
finally:
await page.close()
async def batch_scrape(urls: list[str], concurrency: int = 5):
"""最大5並列でURLリストを処理"""
semaphore = asyncio.Semaphore(concurrency)
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
tasks = [process_url(semaphore, browser, url) for url in urls]
results = await asyncio.gather(*tasks)
await browser.close()
return results
# 使い方
urls = [f"https://example.com/page{i}" for i in range(20)]
results = asyncio.run(batch_scrape(urls, concurrency=5))
success = [r for r in results if r["status"] == "ok"]
print(f"処理完了: {len(success)}/{len(results)}件成功")
よくある質問
QPlaywrightとPuppeteerはどちらが良いですか?
AClaude Codeでの利用であればPlaywrightを推奨します。Playwrightは公式MCPサーバーが提供されており、Claude Codeとの連携がシームレスです。またChromium・Firefox・WebKitの3ブラウザに対応し、非同期APIの設計も洗練されています。Puppeteerは主にChromium専用で、Playwright登場以降は後継として位置づけられています。
QBrowser UseはGPT-4oとClaude、どちらが良いですか?
ABrowser UseのドキュメントではGPT-4oとClaude Sonnetが最も信頼性が高いとされています。Claude Codeユーザーであれば、既にAPIキーを持っていることが多いためClaudeを選ぶのが自然です。モデル名は claude-sonnet-4-6 のように langchain_anthropic.ChatAnthropic に渡します。
Qheadlessモードとheadedモード、どちらを使うべきですか?
A開発・デバッグ時は headless=False でブラウザ画面を表示しながら動作確認するのが効率的です。本番運用や自動化スクリプトでは headless=True(デフォルト)にしてサーバーリソースを節約してください。
QBrowser Useでエージェントが正しく動作しない場合の対処法は?
Aまずタスクの指示文を具体的にする(URLやボタン名を明記する)と成功率が上がります。それでも解決しない場合、max_steps パラメータを増やすことで複雑なタスクも完了できるようになります。また save_conversation_path パラメータでエージェントの行動ログを保存すると、どのステップで詰まっているか確認できます。
QClaude Codeのコンテキストウィンドウが溢れてしまいます。どうすればいいですか?
AMCP経由の利用ではスクリーンショットや完全なアクセシビリティツリーがコンテキストに蓄積されます。CLIやSkillsアプローチに切り替えて結果をファイル経由で渡すことで、大幅にトークン消費を削減できます。Claude Codeのコスト管理ガイドも参考にしてください。
まとめ
PlaywrightとBrowser Useは、それぞれ異なる強みを持つブラウザ自動化ツールです。
| Playwright | Browser Use | |
|---|---|---|
| 強み | 高速・確実・低コスト | 柔軟・適応的・自然言語対応 |
| 弱み | UIが変わると壊れる | 速度・成功率・トークンコスト |
| Claude Code連携 | MCP / CLI / Skills | Pythonライブラリとして直接統合 |
実務ではどちらか一方に絞るのではなく、安定した処理はPlaywright、変動・探索的な処理はBrowser Useと使い分けるハイブリッドアプローチが最も効果的です。また、トークン効率の観点からもMCPよりCLI・Skillsを優先することで、コストを大幅に削減できます。
Claude Codeの他の機能との組み合わせについては、Claude CodeガイドやClaude Agent SDKガイドも参考にしてみてください。

