【Python×Playwright】SPA・動的サイトに対応するモダンWebスクレイピング完全ガイド

【Python×Playwright】SPA・動的サイトに対応するモダンWebスクレイピング完全ガイド

2026/08/11

「スクレイピングで取得したHTMLデータが、JavaScriptの描画前で空っぽだった……」

Webエンジニアとして自動データ収集を行っていると、近年のWebサイト(ReactやVueなどのSPA)で従来の requests + BeautifulSoup の組み合わせが通用しないケースが激増しています。

Seleniumを使う選択肢もありますが、動作が重く環境構築も複雑になりがちです。そこで現在もっとも推奨されるのが、Microsoftが開発するヘッドレスブラウザ自動化ライブラリ Playwright for Python です。今回は、頑丈でエラーに強いスクレイピング基盤の構築手順を徹底解説します。

なぜ Selenium ではなく Playwright なのか?

かつてブラウザ自動化の主流は Selenium でしたが、ドライバのバージョン管理や要素の出現待機(Wait処理)の記述が煩雑で、頻繁にタイムアウトエラーが発生するのが悩みでした。

Playwrightを導入して感動したポイントは以下の3点です。

  1. Auto-waiting(自動待機):要素がクリック可能・表示状態になるまでライブラリ側が自動で待機してくれる。
  2. 高速な実行速度:Chromium, Firefox, WebKit を同一コードで極めて軽量かつ並列に動かせる。
  3. 直感的なデバッグ:コード実行時のスクリーンショットやビデオトレースの採取が標準でサポートされている。

データ取得フローの設計

動的コンテンツの読み込み完了を確実に待ち受け、指定した要素データを抽出して構造化データ(JSON / CSV)として保存する堅牢なワークフローを構築します。

graph TD
    A["スクレイパー起動 (Playwright)"] --> B["ヘッドレスブラウザ起動"]
    B --> C["ターゲットページへナビゲーション"]
    C --> D["特定要素の自動読み込み待機 (Auto-wait)"]
    D --> E{"ページの読み込み成功?"}
    E -- "成功" --> F["DOM要素からテキスト・属性データを抽出"]
    E -- "タイムアウト/異常" --> G["スクリーンショット撮影 & ログ保存"]
    F --> H["JSONファイルへの出力・保存"]
    G --> I["管理者へアラート"]

実践Pythonコード:安全かつ確実なスクレイピング実装

以下は、非同期処理(asyncio)を活用し、複数ページの情報を安定して取得するプロダクションレベルのコード例です。

import asyncio
import json
import logging
from playwright.async_api import async_playwright, TimeoutError as PlaywrightTimeoutError

# ログの設定
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")

TARGET_URL = "https://example.com/products"

async def scrape_product_data():
    async with async_playwright() as p:
        # ヘッドレスブラウザを立ち上げ (Chromium)
        browser = await p.chromium.launch(headless=True)
        # アンチスクレイピング対策としてUser-Agentを設定
        context = await browser.new_context(
            user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
        )
        page = await context.new_page()

        try:
            logging.info(f"ページへアクセス中: {TARGET_URL}")
            # domcontentloaded を待機
            await page.goto(TARGET_URL, wait_until="domcontentloaded", timeout=15000)

            # 動的要素が表示されるまで明示的に待機
            await page.wait_for_selector(".product-card", state="visible", timeout=10000)

            products = []
            cards = await page.query_selector_all(".product-card")
            
            for card in cards:
                title_elem = await card.query_selector(".product-title")
                price_elem = await card.query_selector(".product-price")

                if title_elem and price_elem:
                    title = await title_elem.inner_text()
                    price = await price_elem.inner_text()
                    products.append({"title": title.strip(), "price": price.strip()})

            logging.info(f"正常取得完了: {len(products)} 件のデータを抽出しました")
            
            # 結果をJSON保存
            with open("output.json", "w", encoding="utf-8") as f:
                json.dump(products, f, ensure_ascii=False, indent=2)

        except PlaywrightTimeoutError:
            logging.error("要素の待機中にタイムアウトが発生しました。スクリーンショットを撮影します。")
            await page.screenshot(path="error_timeout.png")
        except Exception as e:
            logging.error(f"予期せぬエラーが発生しました: {e}")
        finally:
            await browser.close()

if __name__ == "__main__":
    asyncio.run(scrape_product_data())

スクリプト構築時の必須テクニック

  1. アクセス相手への配慮(礼儀と間隔) ループ処理で複数ページを巡回する場合は、await asyncio.sleep(2) などで必ず適切なウェイト時間を差し込んでください。アクセス過多によるサーバー過負荷は絶対に避けなければなりません。
  2. タイムアウト時の証拠保存 await page.screenshot(path="error.png") を例外処理に埋め込んでおくと、「デザイン変更でセレクタが変わったのか」「ネットワークエラーか」が即座に判別できます。
  3. robots.txt と利用規約の遵守 スクレイピングを開始する前に、対象ドメインの /robots.txt および利用規約を確認し、収集が許可されている範囲を必ず確認してください。

実際に自動運用して得られた効果

  1. スクレイピング失敗率が90%減少 Selenium時代に頻発していた「原因不明の要素未検出エラー」が、Playwrightの柔軟なAuto-waitによってほぼ絶滅しました。
  2. 取得スピードの高速化 ブラウザコンテキストの軽量化により、1回の収集ジョブにかかる時間が半分以下に削減されました。
  3. 保守工数の大幅削減 トラブル時のスクショ自動生成により、エラー発生から原因特定までの調査時間が10分程度に短縮されました。

まとめ:モダンなツールで堅牢なデータ収集を

JavaScriptが当たり前のように使われる現代のWebにおいて、Playwrightはエンジニアにとって最強の武器になります。

「定期的な価格リサーチ」や「特定サイトの更新チェック」など、日常の手作業を自動化したいと考えている方は、ぜひPlaywrightを試してみてください。驚くほど滑らかで安定した自動化の世界が広がっています!