プログラマー向けモードで表示中ビジネスユーザー向けへ
Bright Data 学習ポータル

Step 5Lv3 ・ 目安 120

Step 5 Browser API + Playwright

Browser API と Playwright を接続し、JS 描画サイトから必要データを抽出する。

この手順を完了すると、Bright Data の Scraping Browser(CDP エンドポイント)に Playwright(Node.js・Python)で接続し、JavaScript 描画サイトやログイン必須サイト、無限スクロールページを自動取得できるようになります。さらに、セッションを保持したままスクリーンショットや PDF を出力し、CAPTCHA 回避の基本パターンも体得できます。

ゴールと所要時間

  • ゴール:Scraping Browser に Playwright を接続し、ログインフロー・無限スクロール・スクリーンショット・PDF 出力を実装
  • 所要時間:120 分
  • 難易度:Lv3(中級)

前提

  • Step 1 が完了していること(Bright Data アカウント取得、API キー取得)
  • Scraping Browser のゾーンが作成済みで、CDP エンドポイントが発行されていること
  • Node.js 20+ または Python 3.9+ がインストール済みで、npm / pip が使用できること
  • 環境変数 BRIGHTDATA_API_KEY に Bright Data の API キーが設定されていること
export BRIGHTDATA_API_KEY=your_api_key_here

Browser API + Playwright 接続フロー — スクリプト → CDP エンドポイント → Scraping Browser → 対象サイト

手順 1: CDP 接続文字列の組立

Scraping Browser の CDP エンドポイントは次の形式です。<CUSTOMER_ID><ZONE_NAME><PASSWORD> は Bright Data コンソールで確認してください。

wss://brd-customer-<CUSTOMER_ID>-zone-<ZONE_NAME>:<PASSWORD>@brd.superproxy.io:9222

例として、環境変数から組み立てるシェルスクリプトを示します。

#!/usr/bin/env bash
CUSTOMER_ID=${BRIGHTDATA_CUSTOMER_ID:-12345}
ZONE_NAME=${BRIGHTDATA_ZONE_NAME:-myzone}
PASSWORD=${BRIGHTDATA_ZONE_PASSWORD:-pwd123}
CDP_URL="wss://brd-customer-${CUSTOMER_ID}-zone-${ZONE_NAME}:${PASSWORD}@brd.superproxy.io:9222"
export BRIGHTDATA_CDP_URL="${CDP_URL}"
echo "CDP URL: $BRIGHTDATA_CDP_URL"

注意:CDP は WebSocket(wss://)プロトコルなので curl で直接叩いて挙動を確認することはできません。実際に接続できるかは Playwright の connectOverCDP で試すのが確実です(後述)。curl -I https://brd.superproxy.io/ で TLS の到達性だけは確認できます。

手順 2: Node.js + Playwright で接続し 1 ページ取得

  1. 必要パッケージをインストールします。
npm init -y
npm i playwright
  1. 接続スクリプト node_playwright_cdp.js を作成します。
// node_playwright_cdp.js
const { chromium } = require('playwright');
 
(async () => {
  const cdpUrl = process.env.BRIGHTDATA_CDP_URL;
  if (!cdpUrl) {
    console.error('BRIGHTDATA_CDP_URL が設定されていません。');
    process.exit(1);
  }
 
  // CDP エンドポイントに接続
  const browser = await chromium.connectOverCDP(cdpUrl);
  const context = await browser.newContext();
  const page = await context.newPage();
 
  // 任意の URL を取得
  await page.goto('https://example.com', { waitUntil: 'networkidle' });
  console.log('ページタイトル:', await page.title());
 
  // 後片付け
  await context.close();
  await browser.close();
})();
  1. 実行します。
BRIGHTDATA_CDP_URL=$BRIGHTDATA_CDP_URL node node_playwright_cdp.js

手順 3: Python + Playwright で同じ接続

  1. パッケージをインストールします。
pip install playwright
python -m playwright install
  1. スクリプト python_playwright_cdp.py を作成します。
# python_playwright_cdp.py
import os
import asyncio
from playwright.async_api import async_playwright
 
async def main():
    cdp_url = os.getenv("BRIGHTDATA_CDP_URL")
    if not cdp_url:
        raise RuntimeError("BRIGHTDATA_CDP_URL が設定されていません。")
 
    async with async_playwright() as p:
        browser = await p.chromium.connect_over_cdp(cdp_url)
        context = await browser.new_context()
        page = await context.new_page()
        await page.goto("https://example.com", wait_until="networkidle")
        title = await page.title()
        print(f"ページタイトル: {title}")
 
        await context.close()
        await browser.close()
 
asyncio.run(main())
  1. 実行します。
BRIGHTDATA_CDP_URL=$BRIGHTDATA_CDP_URL python python_playwright_cdp.py

手順 4: ログインフロー(フォーム入力 → クッキー保存)

以下は例として、GitHub のログインページに対してフォーム入力し、クッキーをローカルに保存する手順です。実際のサイトに合わせてセレクタを変更してください。

Node.js

// login_and_save_cookies.js
const { chromium } = require('playwright');
const fs = require('fs');
 
(async () => {
  const cdpUrl = process.env.BRIGHTDATA_CDP_URL;
  const browser = await chromium.connectOverCDP(cdpUrl);
  const context = await browser.newContext();
  const page = await context.newPage();
 
  await page.goto('https://github.com/login', { waitUntil: 'networkidle' });
  await page.fill('input[name="login"]', process.env.GITHUB_USERNAME);
  await page.fill('input[name="password"]', process.env.GITHUB_PASSWORD);
  await page.click('input[name="commit"]');
  await page.waitForNavigation({ waitUntil: 'networkidle' });
 
  // クッキー取得・保存
  const cookies = await context.cookies();
  fs.writeFileSync('github_cookies.json', JSON.stringify(cookies, null, 2));
  console.log('クッキーを github_cookies.json に保存しました');
 
  await context.close();
  await browser.close();
})();

Python

# login_and_save_cookies.py
import os
import json
import asyncio
from playwright.async_api import async_playwright
 
async def main():
    cdp_url = os.getenv("BRIGHTDATA_CDP_URL")
    async with async_playwright() as p:
        browser = await p.chromium.connect_over_cdp(cdp_url)
        context = await browser.new_context()
        page = await context.new_page()
 
        await page.goto("https://github.com/login", wait_until="networkidle")
        await page.fill('input[name="login"]', os.getenv("GITHUB_USERNAME"))
        await page.fill('input[name="password"]', os.getenv("GITHUB_PASSWORD"))
        await page.click('input[name="commit"]')
        await page.wait_for_navigation(wait_until="networkidle")
 
        cookies = await context.cookies()
        with open("github_cookies.json", "w", encoding="utf-8") as f:
            json.dump(cookies, f, indent=2, ensure_ascii=False)
        print("クッキーを github_cookies.json に保存しました")
 
        await context.close()
        await browser.close()
 
asyncio.run(main())

ポイント:取得したクッキーは後続のリクエストで context.add_cookies(cookies) とすればセッションを再利用できます。

手順 5: 無限スクロール・遅延読み込みの待機パターン

無限スクロールはページの下部までスクロールし、追加コンテンツがロードされるのを待つループで実装します。

Node.js

// infinite_scroll.js
const { chromium } = require('playwright');
 
(async () => {
  const cdpUrl = process.env.BRIGHTDATA_CDP_URL;
  const browser = await chromium.connectOverCDP(cdpUrl);
  const context = await browser.newContext();
  const page = await context.newPage();
 
  await page.goto('https://example-infinite-scroll.com', { waitUntil: 'networkidle' });
 
  // 10 回スクロールしてみる
  for (let i = 0; i < 10; i++) {
    await page.evaluate(() => {
      window.scrollTo(0, document.body.scrollHeight);
    });
    // 新しいコンテンツがロードされるまで 2 秒待機
    await page.waitForTimeout(2000);
  }
 
  // 取得した HTML を保存
  const html = await page.content();
  const fs = require('fs');
  fs.writeFileSync('infinite_scroll.html', html);
  console.log('ページ内容を infinite_scroll.html に保存しました');
 
  await context.close();
  await browser.close();
})();

Python

# infinite_scroll.py
import os
import asyncio
from playwright.async_api import async_playwright
 
async def main():
    cdp_url = os.getenv("BRIGHTDATA_CDP_URL")
    async with async_playwright() as p:
        browser = await p.chromium.connect_over_cdp(cdp_url)
        context = await browser.new_context()
        page = await context.new_page()
 
        await page.goto("https://example-infinite-scroll.com", wait_until="networkidle")
 
        for _ in range(10):
            await page.evaluate("window.scrollTo(0, document.body.scrollHeight);")
            await page.wait_for_timeout(2000)  # 2 秒待機
 
        html = await page.content()
        with open("infinite_scroll.html", "w", encoding="utf-8") as f:
            f.write(html)
        print("ページ内容を infinite_scroll.html に保存しました")
 
        await context.close()
        await browser.close()
 
asyncio.run(main())

手順 6: スクリーンショット / PDF 出力

取得したページをそのままスクリーンショットや PDF に保存できます。

Node.js

// screenshot_and_pdf.js
const { chromium } = require('playwright');
const fs = require('fs');
 
(async () => {
  const cdpUrl = process.env.BRIGHTDATA_CDP_URL;
  const browser = await chromium.connectOverCDP(cdpUrl);
  const context = await browser.newContext();
  const page = await context.newPage();
 
  await page.goto('https://example.com', { waitUntil: 'networkidle' });
 
  // スクリーンショット
  await page.screenshot({ path: 'example.png', fullPage: true });
  console.log('スクリーンショットを example.png に保存');
 
  // PDF(Chromium のみ対応)
  await page.pdf({ path: 'example.pdf', format: 'A4' });
  console.log('PDF を example.pdf に保存');
 
  await context.close();
  await browser.close();
})();

Python

# screenshot_and_pdf.py
import os
import asyncio
from playwright.async_api import async_playwright
 
async def main():
    cdp_url = os.getenv("BRIGHTDATA_CDP_URL")
    async with async_playwright() as p:
        browser = await p.chromium.connect_over_cdp(cdp_url)
        context = await browser.new_context()
        page = await context.new_page()
 
        await page.goto("https://example.com", wait_until="networkidle")
 
        await page.screenshot(path="example.png", full_page=True)
        print("スクリーンショットを example.png に保存")
 
        await page.pdf(path="example.pdf", format="A4")
        print("PDF を example.pdf に保存")
 
        await context.close()
        await browser.close()
 
asyncio.run(main())

ローカル Chrome との違い

項目ローカル ChromeBright Data Scraping Browser
接続方式chrome://inspect(ローカルデバッガ)CDP エンドポイント(wss://…)
帯域自己ネットワークBright Data のプロキシ帯域(自動圧縮・最適化)
タイムアウトローカル環境依存デフォルト 30 s(必要に応じて timeout オプションで変更)
セッション保持ブラウザプロファイルで管理クッキー・ローカルストレージは context に保存し、再利用可能
CAPTCHA 回避手動 or サードパーティーBright Data の自動 CAPTCHA 解決オプション(captcha_solver パラメータ)を併用可能

検証

  1. ページタイトルが取得できているか(例: Example Domain
  2. クッキーgithub_cookies.json に保存され、次回リクエストで context.add_cookies() が成功するか
  3. 無限スクロール後の HTML に期待した要素(例: 商品リスト)が含まれているか
  4. スクリーンショット / PDF が正しく出力され、内容が閲覧できるか

上記がすべてクリアできれば、Step 5 は完了です。

次に読む

  • /usecases/UC-WEB-002 – 大規模 JavaScript 描画サイトの高速抽出
  • /usecases/UC-DEV-009 – CAPTCHAs と対話的ログインのベストプラクティス
  • /hands-on/step-6-mcp-agent – MCP エージェントでのマルチプロキシ制御

以上で「Step 5 Browser API + Playwright」の解説は終了です。お疲れさまでした。