| name | playwright-scraper |
| description | ログイン認証・ページネーション・ダウンロード機能を伴うWebスクレイピング実装に使用。「Playwrightでサイト○○からデータを取得したい」「ログインしてZIPをダウンロードしたい」という依頼で起動。セレクタ自動判定 → スクレイピングロジック実装 → ダウンロード・待機処理の統合で進める。 |
Playwright Scraper
概要
Playwrightを使った動的Webスクレイピング実装ガイド。
静的サイト対応で、ログイン認証・ページネーション・ZIPダウンロードなど、複数ステップの自動化を実装。
作業手順
Step 1: セレクタ自動判定
ユーザーが提供したページソース(HTML)から必要なセレクタを自動判定。
- ページソースをファイルで受け取り(または URL を直接検査)
- セレクタ候補を抽出(ID / Class / XPath)
- JSON形式でセレクタマップを出力(ユーザーが確認/修正可能)
使用ツール: scripts/selector_detector.py で自動判定
{
"login_form": {
"email_input": "#loginId",
"password_input": "#password",
"login_button": "button[type='submit']"
},
"download_link": "a[href*='zip']"
}
Step 2: スクレイピングロジック実装
認証・ページネーション・ダウンロード処理を組み立て。
ログイン処理:
- ブラウザを起動(Chromium推奨)
- フォーム入力 → ログインボタン クリック
- ページロード完了を待機(
page.wait_for_load_state() 利用)
ページネーション:
- セレクタで次ページリンク検出
- 存在するまでループ、ページごと処理
- タイムアウト・重複排除に注意
ダウンロード:
- 事前に download ハンドラ登録 (
page.on("download", handler))
- リンク・ボタン をクリック
- ダウンロード完了を待機
Step 3: エラーハンドリング・ロギング統合
タイムアウト / セレクタ見つからず / ダウンロード失敗 時の対応。
- 具体的な例外で捕捉(
playwright.async_api.TimeoutError など)
- 構造化ログで追跡(
logger.debug() / logger.error() with exc_info)
- リトライ機構は必要に応じて(最大3回程度)
実装例
入力:
target_url: "https://example.com/login"
selectors_file: "config/selectors.json"
credentials:
email: "${EMAIL}"
password: "${PASSWORD}"
download_dir: "./downloads"
page_limit: 5
期待する出力:
${download_dir}/data_*.zip ダウンロード成功
scrape_log.json 構造化ログ(取得項目数・エラー・実行時間)
- セレクタ見つからず時は詳細メッセージ(HTML スナップショット相対パス等)
使用する同梱リソース
ダウンロード完了待機のパターン比較
Playwrightでファイルダウンロードを実装する際、完了待機の方法は2つのパターンがあります:
パターンA: download.path() で完了を待機(推奨)
def handle_download(download):
file_path = Path(download.path())
target_path = self.download_dir / download.suggested_filename
shutil.copy2(file_path, target_path)
return target_path
メリット:
- Playwright標準パターン
- ダウンロード完了を確実に待機
- ファイルが確実に書き込まれたことを保証
- ユーザーはすぐにファイルを使用可能
デメリット: 特になし
パターンB: page.wait_for_load_state("networkidle") で待機
def handle_download(download):
download.save_as(self.download_dir / download.suggested_filename)
page.on("download", handle_download)
page.click(link_selector)
page.wait_for_load_state("networkidle")
メリット:
デメリット:
- ダウンロード完了を保証しない
- ファイル書き込み完了前に処理が進む可能性
- race conditionのリスク
推奨: パターンA(download.path())を使用してください。basic_scraper.pyはこのパターンで実装されています。
チェックリスト
実装完了時に以下を確認: