第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や機能が変更される可能性があります。最新情報は公式ドキュメントをご確認ください。
本コンテンツは2025年12月時点の情報に基づいて作成されています。Node.jsおよび関連ツールは活発に開発が進められており、APIや機能が変更される可能性があります。最新情報は公式ドキュメントをご確認ください。