第6章 Playwright連携

更新日:2025年12月17日

本章では、Node.jsからブラウザを自動操作するためのライブラリ「Playwright」について解説する。Seleniumとの違い、基本的な操作方法、待機処理、エラーハンドリングを学ぶ。自動発注エージェントなど、ブラウザ操作を伴うシステム開発の基礎となる知識である。

1. Playwrightとは

1.1 概要

Playwrightは、Node.jsからブラウザを自動操作するためのライブラリである。Microsoft社が2020年に公開した。

Fig. 1 Playwrightの位置づけ

┌─────────────────┐
│ 自分のコード     │  ← Node.jsで書く
│ (JavaScript)    │
└────────┬────────┘
         │
         ↓ Playwrightで操作
┌─────────────────┐
│ ブラウザ         │  ← Chrome、Firefox、Safari
│ (自動で動く)    │
└─────────────────┘

1.2 Seleniumとの比較

ブラウザ自動操作のツールとしては、Selenium(2004年)が先行していた。Playwrightは後発の利点を活かし、過去のツールの問題点を解決している。

Table 1. SeleniumとPlaywrightの比較

観点 Selenium Playwright
登場 2004年 2020年
開発元 Selenium Project Microsoft
速度 遅め 速い
安定性 不安定になりやすい 安定
待機処理 自分で書く必要あり 自動で待ってくれる

1.3 自動待機の違い

最大の違いは「待機処理」である。Webページは読み込みに時間がかかるため、要素が表示される前に操作しようとするとエラーになる。

Selenium:
ページ読込中... → クリック実行 → 要素がない! → エラー
                  (待ってくれない)

Playwright:
ページ読込中... → 要素を探す → まだない → 待機 → 見つけた → クリック
                  (自動で待ってくれる)
// Selenium:自分で待機処理を書く必要がある
await driver.wait(until.elementLocated(By.id('button')), 10000);
await driver.findElement(By.id('button')).click();

// Playwright:自動で待ってくれる
await page.click('#button');

1.4 歴史的経緯

Playwrightの開発者は、元々Googleで「Puppeteer」を開発していた人たちである。

Selenium(2004年)
    ↓ Chromeに特化して高速化
Puppeteer(2017年、Google)
    ↓ 複数ブラウザ対応 + さらに改良
Playwright(2020年、Microsoft)

2. 基本的な使い方

2.1 インストール

npm install playwright

初回はブラウザ(Chrome、Firefox、Safari)もダウンロードされる。

2.2 最小のコード

const { chromium } = require('playwright');

async function main() {
    const browser = await chromium.launch();
    const page = await browser.newPage();
    
    await page.goto('https://example.com');
    
    console.log(await page.title());
    
    await browser.close();
}

main();

2.3 browserとpageの関係

browserはブラウザ本体、pageはタブ1つを表す。

Fig. 2 browserとpageの関係

┌─────────────────────────────────────────┐
│ browser(ブラウザ本体)                  │
│                                         │
│  ┌─────────┐ ┌─────────┐ ┌─────────┐   │
│  │ page1   │ │ page2   │ │ page3   │   │
│  │ (タブ1) │ │ (タブ2) │ │ (タブ3) │   │
│  └─────────┘ └─────────┘ └─────────┘   │
└─────────────────────────────────────────┘
const browser = await chromium.launch();

// タブを複数開く
const page1 = await browser.newPage();
const page2 = await browser.newPage();
const page3 = await browser.newPage();

// それぞれ別のサイトにアクセス
await page1.goto('https://google.com');
await page2.goto('https://yahoo.co.jp');
await page3.goto('https://example.com');

await browser.close();  // 全タブを閉じる

3. 要素の操作

3.1 セレクタ

操作対象の要素を指定する方法である。

// CSSセレクタ
await page.click('#submit');           // id="submit"
await page.click('.button');           // class="button"
await page.click('button');            // タグ名

// テキストで指定
await page.click('text=ログイン');      // 「ログイン」という文字

// 複合
await page.click('button.primary');    // class="primary"のbutton

3.2 主要な操作

Table 2. 主要な操作一覧

操作 コード
クリック await page.click('#button')
文字入力 await page.fill('#input', '文字')
テキスト取得 await page.textContent('#element')
待機 await page.waitForSelector('#element')
スクリーンショット await page.screenshot({ path: 'screenshot.png' })

3.3 ログイン操作の例

// HTML:
// <input type="text" id="username" />
// <input type="password" id="password" />
// <button id="login">ログイン</button>

// ユーザー名を入力
await page.fill('#username', 'tanaka');

// パスワードを入力
await page.fill('#password', 'pass123');

// ログインボタンをクリック
await page.click('#login');

4. 実行モード

Playwrightには2つの実行モードがある。

Table 3. 実行モードの比較

モード 画面 用途
ヘッドフル 表示される 開発中、デバッグ
ヘッドレス 表示されない 本番運用、サーバー実行
// ヘッドフル(画面表示)
const browser = await chromium.launch({ headless: false });

// ヘッドレス(画面非表示)※デフォルト
const browser = await chromium.launch({ headless: true });

5. 待機処理

5.1 よく使う待機パターン

Table 4. 待機パターン一覧

パターン コード 用途
要素が表示されるまで await page.waitForSelector('#element') 動的に表示される要素
ページ遷移完了まで await page.waitForNavigation() ログイン後など
指定時間待機 await page.waitForTimeout(1000) 1秒待つ(非推奨)
ネットワーク完了まで await page.waitForLoadState('networkidle') Ajax完了待ち

5.2 ページ遷移の待機

// クリックとページ遷移を同時に待つ
await Promise.all([
    page.waitForNavigation(),
    page.click('#login')
]);

5.3 固定時間待機は非推奨

// 悪い例:固定時間待機
await page.waitForTimeout(3000);  // 3秒待つ

// 良い例:条件で待機
await page.waitForSelector('#result');  // 要素が出るまで待つ

固定時間は遅すぎても速すぎても問題が起きる。条件で待機する方が安定する。

6. エラーハンドリング

6.1 基本パターン

try {
    await page.click('#button', { timeout: 5000 });  // 5秒でタイムアウト
} catch (error) {
    console.log('ボタンが見つかりませんでした');
    // 代替処理やリトライ
}

Table 5. エラー対処パターン

パターン 説明
タイムアウト 一定時間で諦める
リトライ 失敗したら再試行
スクリーンショット エラー時の状態を保存
ログ出力 原因調査用に記録

6.2 実践的なエラーハンドリング

async function login(page, username, password) {
    try {
        await page.fill('#username', username);
        await page.fill('#password', password);
        await page.click('#login', { timeout: 5000 });
        await page.waitForNavigation();
        
        console.log('ログイン成功');
        return true;
        
    } catch (error) {
        console.log('ログイン失敗:', error.message);
        
        // エラー時のスクリーンショット
        await page.screenshot({ path: 'error.png' });
        
        return false;
    }
}

6.3 リトライ処理

async function clickWithRetry(page, selector, maxRetries = 3) {
    for (let i = 0; i < maxRetries; i++) {
        try {
            await page.click(selector);
            return true;  // 成功
        } catch (error) {
            console.log(`試行 ${i + 1} 失敗、リトライ...`);
            await page.waitForTimeout(1000);
        }
    }
    return false;  // 全て失敗
}

7. エージェント開発との関係

自動発注エージェントでは、Playwrightを中心に各技術が連携する。

Fig. 3 エージェント開発の全体像

┌─────────────────────────────────────────────────────┐
│ 自動発注エージェント                                 │
│                                                     │
│  ┌─────────────┐    ┌─────────────┐    ┌─────────┐ │
│  │ Node.js     │ → │ Playwright  │ → │ ブラウザ │ │
│  │ (制御)      │    │ (操作)      │    │ (実行)  │ │
│  └─────────────┘    └─────────────┘    └─────────┘ │
│         ↑                                          │
│  ┌─────────────┐                                   │
│  │ LangChain   │  ← AIが判断・指示                 │
│  │ (AI連携)    │                                   │
│  └─────────────┘                                   │
└─────────────────────────────────────────────────────┘

Table 6. 各技術の役割

技術 役割
Node.js 全体を動かす実行環境
Express.js 外部からの指示を受け取る(API)
Playwright ブラウザを自動操作
LangChain AIと連携して判断させる
処理の流れ:
1. 「この商品を10個発注して」という指示
        ↓
2. LangChain(AI)が指示を解釈
        ↓
3. Node.jsが処理を組み立てる
        ↓
4. Playwrightがブラウザを操作
        ↓
5. 発注完了

8. まとめ

Table 7. 第6章のまとめ

概念 内容
Playwright ブラウザ自動操作ライブラリ(Microsoft、2020年)
Seleniumとの違い 自動待機、高速、安定
browser ブラウザ本体
page タブ1つ
セレクタ 操作対象の要素を指定(#id、.class、text=)
ヘッドレス/ヘッドフル 画面非表示/表示モード
待機処理 条件待機を推奨(固定時間は非推奨)
エラーハンドリング タイムアウト、リトライ、スクリーンショット
参考・免責事項
本コンテンツは2025年12月時点の情報に基づいて作成されています。Node.jsおよび関連ツールは活発に開発が進められており、APIや機能が変更される可能性があります。最新情報は公式ドキュメントをご確認ください。