最近WebテストやWeb操作の自動化やスクレイピングでPlaywrightを利用しています。コーディングしている際に何度も検索をして確認しているのでこちらにチートシートを作成してこちらの1ページで全部確認できるようにしていきます。(基本、新しいPlaywrightのコーディングが分かったら都度追加していく)
言語は一番使っているPythonで記述します。
playwright と undetected_playwright の違い
以下のようにundetected_playwrightライブラリを利用できます。
from undetected_playwright.async_api import async_playwright
Playwright
Microsoft 製の公式ブラウザ自動化ライブラリです。今でスクレイピングする際は Selenium を利用していましたが、Playwright はより新しく、高速で安定した自動操作が可能です。playwright.async_api を使えば非同期(async/await)でブラウザを操作できます。
undetected_playwright
bot 検知を回避する工夫 を加えた非公式ライブラリです。通常の Playwright だと「自動操作ツール」と検知されて弾かれるサイトがありますが、undetected_playwright はそれを回避しやすくしています。とは言っても動きが機械的ならすぐにツールだと検知されます。特に魔法のようにすごいことをやっているわけではありません。
基本方針
locator を最優先にする
locator は、自動待機(Auto‑wait)付きでなので wait_for_selector が不要になる。
デフォルトは30秒。
安定セレクタを使う
id / data-testid / role / label を優先する。
脆い XPath は最後の手段にする。
“待つ理由” を明確にする
DOM出現、可視化、可操作(enabled)、ネットワーク静穏など、目的に合わせて wait を選ぶ。
ログインID&パスワード入力時(推奨パターン)
login_id = page.get_by_label("ログインID")
await login_id.fill(account)
ラベル紐付けで取得できるか確認する。XPathは変わる可能性があるが、ラベルが変わるということはあまりない想定。アクセシビリティに強くなる。
特定のURLのページに移動する場合
以下のように特定のページに移動したい場合があります。
await page.goto("https://www.xxxxxx.co.jp/login.html", wait_until="domcontentloaded")
その場合、確実に表示が完了してから次の操作に移りたい場合は、wait_until=”domcontentloaded を入れることができます。
wait_until=”domcontentloaded” は、DOM構造が読み込まれた時点で待機を終えます。更に画像やJavaScriptのロードは待ちません。つまり「最低限のHTMLができあがった瞬間」に処理を進められます。JavaScriptで作成されたページや画像のロードを待たなければいけないページでは利用できませんが、シンプルなログインページなどでは利用できます。
クリックをする場合
ボタンなどの要素をクリックしたい場合は以下のようにします。
# ボタンの要素を変数に代入する
top_menu = page.locator('xpath=xxxxxxxxxxxxxx')
# state="visible" で、要素が画面に表示されるまで待つ
await top_menu.wait_for(state="visible", timeout=30000)
# 要素をクリックする。
await top_menu.click(timeout=60000)
state=”visible” は、DOMに存在・非表示でない・サイズがある(クリック対象になり得る)状態です。最大で30秒待ちます。
idで指定する場合
ID値 → id 属性で指定(例:#auto-logout)
#xxxxでID値で指定していることになります。
ページの遷移が発生する場合
ページの遷移(移動)が発生する場合は、タイミングによっては async with を入れて、待ちながらクリックをするようにします。
print("ログインボタンをクリックします。")
# ページの遷移が発生するので async with で待ちながらボタンをクリックして取りこぼしがないようにします。
async with page.expect_navigation():
await page.locator('xpath=xxxxxxxxx').click()
以下のように 「クリックをする」 → 「待つ」 だとすでにページが遷移してしまうとイベントが終わっていてタイムアウトになる可能性があるからです。
await page.click("text=ログイン")
await page.wait_for_navigation()
try exceptの例外処理(エラーハンドリング)を入れる
playwrightでスクレイピングをすると時に思いもよらぬ原因でエラーになることがあります。しかしエラーになったらプログラムが停止してしまったら都合が悪い場合もあります。また、エラーの原因を確認し改善したいです。
そのような場合に try except の例外処理を入れます。特に常時起動してスクレイピングをするようなプログラムの場合はちょっとしたエラーで停止してほしくはありません。
以下のように try except を導入します。
try:
await function_xxxxxx(xxxxxx)
except Exception as e:
print(f"function_xxxxxx の処理でエラーが発生しました: {e}")
import traceback
traceback.print_exc() # 詳細なスタックトレースを出す
print("この関数をスキップして次に進みます。\n")
continue
コメント