browser-automation について
Playwright によるウェブスクレイピングやブラウザー操作を構築する開発者向けのスキルです。データ抽出、フォーム入力、スクリーンショット、セッション管理、動的コンテンツやリトライを扱います。
主な機能
- 01ページから構造化データを抽出
- 02フォームや複数段階の操作を自動化
- 03スクリーンショットと PDF を取得
- 04ブラウザーセッションを保存・復元
- 05動的コンテンツとリトライに対応
- 06自動化検出リスクを点検
活用シーン
- 01ページ分割された一覧からデータを収集
- 02認証済みポータルの操作を完了
- 03ページや要素のスクリーンショットを取得
- 04再利用可能なブラウザーデータパイプラインを構築
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ alirezarezvani/ claude-skills --skill browser-automationインストール後、Claude Code で/browser-automationを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/anti_detection_patterns.mddata_extraction_recipes.mdplaywright_browser_api.mdscripts/anti_detection_checker.pyform_automation_builder.pyscraping_toolkit.py詳細
ブラウザー自動化 - 強力
概要
Browser Automation スキルは、Playwright を使用した本番環境向けの Web 自動化ワークフローを構築するための、包括的なツールと知識を提供します。このスキルでは、信頼性の高い大規模なブラウザー自動化に必要な、データ抽出、フォーム入力、スクリーンショットの撮影、セッション管理、検出回避のパターンを扱います。
このスキルを使用する場面:
- Web サイトから構造化データ(テーブル、一覧、検索結果)をスクレイピングする
- 複数ステップのブラウザーワークフロー(ログイン、フォーム入力、ファイルのダウンロード)を自動化する
- Web ページのスクリーンショットや PDF を作成する
- SPA や JavaScript を多用するサイトからデータを抽出する
- 繰り返し実行可能なブラウザーベースのデータパイプラインを構築する
このスキルを使用しない場面:
- ブラウザーテストや E2E テストスイートを作成する場合 — 代わりに playwright-pro を使用してください
- API エンドポイントをテストする場合 — 代わりに api-test-suite-builder を使用してください
- 負荷テストやパフォーマンスベンチマークを行う場合 — 代わりに performance-profiler を使用してください
Selenium や Puppeteer より Playwright を選ぶ理由:
- 自動待機機能を標準搭載 — ほとんどの操作で明示的な
sleep()やwaitForElement()は不要です - 1 つの API で複数のブラウザーに対応 — 設定を変更せずに Chromium、Firefox、WebKit を使用できます
- ネットワークのインターセプト — 広告のブロック、レスポンスのモック、API 呼び出しのキャプチャーをネイティブに実行できます
- ブラウザーコンテキスト — 新しいブラウザーインスタンスを起動せずに、セッションを分離できます
- コード生成 —
playwright codegenで操作を記録し、スクリプトを生成できます - 非同期処理を優先 — 高スループットのスクレイピングに Python の async/await を使用できます
主な能力
1. Web スクレイピングのパターン
セレクターの優先順位(信頼性の高い順):
data-testid、data-id、またはカスタムデータ属性 — デザイン変更後も安定しています#idセレクター — 一意ですが、デプロイのたびに変わる場合があります- セマンティックセレクター:
article、nav、main、section— CSS の変更に強いです - クラスベース:
.product-card、.price— クラスが生成される場合(例:CSS モジュール)、壊れやすくなります - 位置ベース:
nth-child()、nth-of-type()— 最後の手段です。レイアウト変更で動作しなくなります
CSS では関係を表現できない場合(例:祖先要素の走査、テキストベースの選択)のみ、XPath を使用してください。
ページネーションの方法: 次へボタン、URL ベース(?page=N)、無限スクロール、さらに読み込むボタン。ページネーションのハンドラーとスクロールのパターンについては、data_extraction_recipes.md を参照してください。
2. フォーム入力と複数ステップのワークフロー
複数ステップのフォームは、ステップごとに個別の関数に分割します。各関数でフィールドに入力し、「次へ」/「続行」をクリックして、次のステップが読み込まれる(URL の変更または DOM 要素の表示)まで待機します。
主なパターン:ログインフロー、複数ページのフォーム、ファイルのアップロード(ドラッグ&ドロップ領域を含む)、標準およびカスタムのドロップダウンの処理。fill()、select_option()、set_input_files()、expect_file_chooser() の完全な API リファレンスについては、playwright_browser_api.md を参照してください。
3. スクリーンショットと PDF の作成
- ページ全体:
await page.screenshot(path="full.png", full_page=True) - 要素:
await page.locator("div.chart").screenshot(path="chart.png") - PDF(Chromium のみ):
await page.pdf(path="out.pdf", format="A4", print_background=True) - ビジュアルリグレッション: 既知の状態でスクリーンショットを撮影し、
{page}_{viewport}_{state}.pngという命名規則でベースラインをバージョン管理システムに保存します
スクリーンショットと PDF の全オプションについては、playwright_browser_api.md を参照してください。
4. 構造化データの抽出
主な抽出パターン:
- テーブルから JSON へ —
<thead>のヘッダーと<tbody>の行を辞書に抽出します - 一覧から配列へ — フィールドセレクターのマップを使用して、繰り返されるカード要素をマッピングします(属性用の
::attr()に対応) - 入れ子状/スレッド状のデータ — 返信付きコメントやカテゴリーツリーを再帰的に抽出します
抽出関数、価格の解析、データクリーニング用ユーティリティ、出力形式のヘルパー(JSON、CSV、JSONL)については、data_extraction_recipes.md を参照してください。
5. Cookie とセッションの管理
- Cookie の保存と復元:
context.cookies()とcontext.add_cookies() - ストレージ状態全体(Cookie + localStorage):保存するには
context.storage_state(path="state.json")、復元するにはbrowser.new_context(storage_state="state.json")を使用します
ベストプラクティス: ログイン後に状態を保存し、スクレイピングセッション間で再利用します。長時間のジョブを開始する前に、セッションが有効か確認してください。保護されたページに軽量なリクエストを送信し、ログインページにリダイレクトされていないことを確認します。Cookie とストレージ状態の API の詳細は、playwright_browser_api.md を参照してください。
6. 検出回避のパターン
最新の Web サイトでは、複数の要素を通じて自動化を検出します。次の優先順位に従って適用してください。
- WebDriver フラグの削除 — 初期化スクリプトを使用して
navigator.webdriver = trueを削除します(重要) - カスタムユーザーエージェント — 実際のブラウザーの UA を切り替えて使用します。デフォルトのヘッドレス UA は使用しないでください
- 現実的なビューポート — 1920x1080 など、実環境に近いサイズを設定します(デフォルトの 800x600 は不審に見えます)
- リクエストのスロットリング — 操作の間に
random.uniform()による遅延を追加します - プロキシのサポート — ブラウザーごと、またはコンテキストごとにプロキシを設定します
完全なステルス構成(navigator プロパティの強化、WebGL/canvas フィンガープリントの回避、マウスの動き・タイピング速度・スクロールパターンの動作シミュレーション、プロキシローテーション戦略、検出セルフテスト用 URL)については、anti_detection_patterns.md を参照してください。
7. 動的コンテンツの処理
- SPA のレンダリング: ページのロードイベントではなく、コンテンツのセレクターを待機します(
wait_for_selector) - AJAX/Fetch の待機:
page.expect_response("**/api/data*")を使用して、特定の API 呼び出しを捕捉して待機します - Shadow DOM: Playwright は
>>演算子を使って、オープンな Shadow DOM を横断できます:page.locator("custom-element >> .inner-class") - 遅延読み込み画像:
scroll_into_view_if_needed()で要素を表示領域内にスクロールし、読み込みを開始します
待機戦略、ネットワークのインターセプト、Shadow DOM の詳細については、playwright_browser_api.md を参照してください。
8. エラー処理と再試行ロジック
- バックオフを伴う再試行: 指数バックオフ(例:1 秒、2 秒、4 秒)を用いた再試行ロジックでページ操作を囲みます
- 代替セレクター:
TimeoutErrorが発生した場合、失敗する前に別のセレクターを試します - エラー状態のスクリーンショット: 想定外の失敗が発生した場合、デバッグ用に
page.screenshot(path="error-state.png")でキャプチャします - レート制限の検出: HTTP 429 のレスポンスを確認し、
Retry-Afterヘッダーに従います
指数バックオフの完全な実装とレートリミッタークラスについては、anti_detection_patterns.md を参照してください。
ワークフロー
ワークフロー 1:単一ページからのデータ抽出
シナリオ: JavaScript でレンダリングされたコンテンツを含む単一ページから、商品データを抽出します。
手順:
- 開発中はヘッドありモードでブラウザーを起動し(
headless=False)、本番環境ではヘッドレスに切り替えます - URL に移動し、コンテンツのセレクターを待機します
- フィールドマッピングを使用して
query_selector_allでデータを抽出します - 抽出したデータを検証します(null 値と想定される型を確認します)
- JSON として出力します
async def extract_single_page(url, selectors):
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
context = await browser.new_context(
viewport={"width": 1920, "height": 1080},
user_agent="Mozilla/5.0 ..."
)
page = await context.new_page()
await page.goto(url, wait_until="networkidle")
data = await extract_listings(page, selectors["container"], selectors["fields"])
await browser.close()
return data
ワークフロー 2:ページネーションを使った複数ページのスクレイピング
シナリオ: 50 ページ以上にわたる検索結果をスクレイピングします。
手順:
- 検出回避設定を使ってブラウザーを起動します
- 最初のページに移動します
- 現在のページからデータを抽出します
- 「次へ」ボタンが存在し、有効になっているか確認します
- 次へ進み、新しいコンテンツが読み込まれるまで待機します(ページ遷移だけでは不十分です)
- 次のページがなくなるか、最大ページ数に達するまで繰り返します
- 一意のキーで結果の重複を除去します
- 出力を逐次書き込みます(すべてをメモリに保持しないでください)
async def scrape_paginated(base_url, selectors, max_pages=100):
all_data = []
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
page = await (await browser.new_context()).new_page()
await page.goto(base_url)
for page_num in range(max_pages):
items = await extract_listings(page, selectors["container"], selectors["fields"])
all_data.extend(items)
next_btn = page.locator(selectors["next_button"])
if await next_btn.count() == 0 or await next_btn.is_disabled():
break
await next_btn.click()
await page.wait_for_selector(selectors["container"])
await human_delay(800, 2000)
await browser.close()
return all_data
ワークフロー 3:認証が必要なワークフロー自動化
シナリオ: ポータルにログインし、複数ステップのフォームを操作して、レポートをダウンロードします。
手順:
- 既存のセッション状態ファイルを確認します
- セッションがない場合は、ログインして状態を保存します
- 保存したセッションを使用して、目的のページに移動します
- 提供されたデータを使用して、複数ステップのフォームに入力します
- ダウンロードが開始されるまで待ちます
- ダウンロードしたファイルを目的のディレクトリに保存します
async def authenticated_workflow(credentials, form_data, download_dir):
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
state_file = "session_state.json"
# Restore or create session
if os.path.exists(state_file):
context = await browser.new_context(storage_state=state_file)
else:
context = await browser.new_context()
page = await context.new_page()
await login(page, credentials["url"], credentials["user"], credentials["pass"])
await context.storage_state(path=state_file)
page = await context.new_page()
await page.goto(form_data["target_url"])
# Fill form steps
for step_fn in [fill_step_1, fill_step_2]:
await step_fn(page, form_data)
# Handle download
async with page.expect_download() as dl_info:
await page.click("button:has-text('Download Report')")
download = await dl_info.value
await download.save_as(os.path.join(download_dir, download.suggested_filename))
await browser.close()
ツールのリファレンス
| スクリプト | 目的 | 主なフラグ | 出力 |
|---|---|---|---|
scraping_toolkit.py | Playwright のスクレイピングスクリプトのひな形を生成します | --url、--selectors、--paginate、--output | Python スクリプトまたは JSON 設定 |
form_automation_builder.py | フィールド仕様からフォーム入力自動化スクリプトを生成します | --fields、--url、--output | Python 自動化スクリプト |
anti_detection_checker.py | Playwright スクリプトの検出要因を監査します | --file、--verbose | スコア付きリスクレポート |
すべてのスクリプトは標準ライブラリのみを使用します。使用方法の詳細は python3 <script> --help を実行して確認してください。
避けるべきパターン
固定時間の待機
悪い例: 各操作の前に await page.wait_for_timeout(5000) を実行します。
良い例: wait_for_selector、wait_for_url、expect_response、または wait_for_load_state を使用します。固定時間の待機は不安定で、処理も遅くなります。
エラーからの復旧がない
悪い例: 最初の失敗でクラッシュする直線的なスクリプトです。 良い例: 各ページ操作を try/except で囲みます。エラー状態のスクリーンショットを撮影します。指数バックオフを使った再試行を実装します。
robots.txt を無視する
悪い例: robots.txt の指示を確認せずにスクレイピングします。
良い例: スクレイピングの前に robots.txt を取得して解析します。Crawl-delay を遵守します。許可されていないパスはスキップします。大規模に実行する場合は、User-Agent にボット名を追加します。
スクリプトに認証情報を保存する
悪い例: Python ファイルにユーザー名とパスワードをハードコードします。
良い例: 環境変数、.env ファイル(Git の追跡対象外)、またはシークレットマネージャーを使用します。CLI 引数で認証情報を渡します。
レート制限がない
悪い例: 1 秒あたり 100 リクエストでサイトに大量のリクエストを送信します。 良い例: リクエスト間にランダムな遅延を追加します(礼儀正しいスクレイピングでは 1~3 秒)。429 応答がないか監視します。指数バックオフを実装します。
セレクターの脆弱性
悪い例: 自動生成されたクラス名(.css-1a2b3c)や深いネスト(div > div > div > span:nth-child(3))に依存します。
良い例: データ属性、セマンティック HTML、またはテキストベースのロケーターを使用します。まずブラウザーの DevTools でセレクターをテストします。
ブラウザーインスタンスをクリーンアップしない
悪い例: ブラウザーを閉じずに起動し、リソースリークを引き起こします。
良い例: browser.close() が必ず呼び出されるよう、常に try/finally または非同期コンテキストマネージャーを使用します。
本番環境で画面表示モードを実行する
悪い例: 本番環境や CI で headless=False を使用します。
良い例: デバッグには画面表示モードを使って開発し、デプロイ時には headless=True を使用します。環境変数で切り替えます:headless = os.environ.get("HEADLESS", "true") == "true"。
関連項目
- playwright-pro — ブラウザーテストのスキルです。E2E テスト、テストアサーション、テストフィクスチャに使用します。Browser Automation はデータ抽出とワークフロー自動化向けであり、テスト向けではありません。
- api-test-suite-builder — ウェブサイトに公開 API がある場合は、レンダリングされたページをスクレイピングする代わりに、API に直接リクエストします。より高速で、信頼性が高く、検出されにくくなります。
- performance-profiler — 自動化スクリプトの処理が遅い場合は、並行処理を追加する前にボトルネックをプロファイリングします。
- env-secrets-manager — 認証が必要な自動化ワークフローで使用する認証情報を安全に管理します。