0
0

More than 1 year has passed since last update.

Playwrightをpythonで使ってみた

Last updated at Posted at 2022-08-25

Playwrightとは?

E2E自動テストの作成を助けてくれるフレームワーク
公式:https://playwright.dev/
githug:https://github.com/microsoft/playwright
TypeScriptやJavaScriptで扱うのが基本っぽい
これ以外でも当記事で扱うPythonの他、Javaや.Netもサポートしている

インストール

参考

環境

Windows10Pro
Python3.8.8

公式の通りにコマンドを打ち込んでいったら動いた (から、公式を見た方が良い)

# pytest(pythonのテストフレームワーク)のプラグインをインストール
pip install pytest-playwright

# 必要なブラウザのインストール
playwright install

これでインストールは完了

操作を記録する

ここではgoogleの検索を実行する操作を記録する
https://www.google.com/

操作を記録するコマンド
Playwright codegen【対象ページのURL】-o【出力ファイルパス】

# 操作の記録をpythonのコードで現在のフォルダ配下に保存する
Playwright codegen https://www.google.com/ -o PlaywrightSample.py

これを実行するとブラウザが起動し、googleのページが表示する
image.png

検索ボックスに「今日の天気」を入力し、Enterを押下する
image.png

検索結果が出てくることを確認して、ブラウザを閉じる
image.png

ここまでやって、コマンドプロンプト上の現在のフォルダを確認すると、pythonコードが出来上がっている
image.png

こんな感じのソースが出力される

PlaywrightSample.py
from playwright.sync_api import Playwright, sync_playwright, expect


def run(playwright: Playwright) -> None:
    browser = playwright.chromium.launch(headless=False)
    context = browser.new_context()

    # Open new page
    page = context.new_page()

    # Go to https://www.google.com/
    page.goto("https://www.google.com/")

    # Click text=ログインせずに使う
    page.frame_locator("iframe[role=\"presentation\"]").locator("text=ログインせずに使う").click()

    # Click [aria-label="検索"]
    page.locator("[aria-label=\"検索\"]").click()

    # Fill [aria-label="検索"]
    page.locator("[aria-label=\"検索\"]").fill("今日の天気")

    # Click [aria-label="検索"]
    page.locator("[aria-label=\"検索\"]").click()

    # Press Enter
    page.locator("[aria-label=\"検索\"]").press("Enter")
    page.wait_for_url("https://www.google.com/search?q=%E4%BB%8A%E6%97%A5%E3%81%AE%E5%A4%A9%E6%B0%97&source=hp&ei=pJoEY-CECavs2roP9IGkqA0&iflsig=AJiK0e8AAAAAYwSotFt-9IhNDjLm4nMhtp0zg_Urj1OT&ved=0ahUKEwjg5oyF0Nz5AhUrtlYBHfQACdUQ4dUDCAk&uact=5&oq=%E4%BB%8A%E6%97%A5%E3%81%AE%E5%A4%A9%E6%B0%97&gs_lcp=Cgdnd3Mtd2l6EAMyDQgAEIAEEMkDEEYQgAIyBQgAEJIDMgUIABCSAzIFCAAQgAQyCAgAELEDEIMBMgUIABCABDIFCAAQgAQyCwgAEIAEELEDELEDMggIABCxAxCDATIFCAAQgAQ6CAgAEI8BEOoCOgYIABAEEAM6DQgAEIAEELEDEIMBEAQ6BwgAEIAEEAQ6CggAEIAEELEDEAQ6EAgAEIAEELEDEIMBEMkDEAQ6FQgAEIAEELEDEIMBEMkDEAQQRhCAAjoSCAAQgAQQsQMQgwEQBBBGEIACOg8IABCABBDJAxAEEEYQgAI6GQgAEIAEELEDEIMBELEDEIMBEMkDEEYQgAI6EQgAEIAEELEDEIMBELEDEIMBOh0IABCABBCxAxCDARCxAxCDARDJAxAEECUQRhCAAjoVCAAQgAQQsQMQgwEQsQMQgwEQBBAlOgkIABCABBAEECU6CAgAEAQQAxAlOgwIABCABBCxAxAEECU6FwgAEIAEELEDEIMBEMkDEAQQJRBGEIACOg8IABCABBCxAxCDARAEECVQ9wpYqz1guewBaAlwAHgAgAH5AYgByRGSAQYxMS43LjKYAQCgAQGwAQo&sclient=gws-wiz")

    # ---------------------
    context.close()
    browser.close()


with sync_playwright() as playwright:
    run(playwright)

当たり前だけど、ログイン確認やいくつかのクリックなど、目的の操作とは直接関係のないものが入り込んでいるので、整理する

また、このまま実行してしまうとpage.wait_for_url()のところでタイムアウトエラーになる
根本的な原因がはっきりしないが、今は動かすことを優先し、代替えの処理に差し替える
page.wait_for_selector()を使って、特定のイメージ(今回はgoogleのロゴ)が表示するまで待つようにしてみた

PlaywrightSample.py
from playwright.sync_api import Playwright, sync_playwright, expect


def run(playwright: Playwright) -> None:
    browser = playwright.chromium.launch(headless=False)
    context = browser.new_context()

    # Open new page
    page = context.new_page()

    # Go to https://www.google.com/
    page.goto("https://www.google.com/")

    # Fill [aria-label="検索"]
    page.locator("[aria-label=\"検索\"]").fill("今日の天気")

    # Press Enter
    page.locator("[aria-label=\"検索\"]").press("Enter")
    page.wait_for_selector("img[alt=\"Google\"]")
    #page.wait_for_url(url="https://www.google.com/search?q=%E4%BB%8A%E6%97%A5%E3%81%AE%E5%A4%A9%E6%B0%97&source=hp&ei=pJoEY-CECavs2roP9IGkqA0&iflsig=AJiK0e8AAAAAYwSotFt-9IhNDjLm4nMhtp0zg_Urj1OT&ved=0ahUKEwjg5oyF0Nz5AhUrtlYBHfQACdUQ4dUDCAk&uact=5&oq=%E4%BB%8A%E6%97%A5%E3%81%AE%E5%A4%A9%E6%B0%97&gs_lcp=Cgdnd3Mtd2l6EAMyDQgAEIAEEMkDEEYQgAIyBQgAEJIDMgUIABCSAzIFCAAQgAQyCAgAELEDEIMBMgUIABCABDIFCAAQgAQyCwgAEIAEELEDELEDMggIABCxAxCDATIFCAAQgAQ6CAgAEI8BEOoCOgYIABAEEAM6DQgAEIAEELEDEIMBEAQ6BwgAEIAEEAQ6CggAEIAEELEDEAQ6EAgAEIAEELEDEIMBEMkDEAQ6FQgAEIAEELEDEIMBEMkDEAQQRhCAAjoSCAAQgAQQsQMQgwEQBBBGEIACOg8IABCABBDJAxAEEEYQgAI6GQgAEIAEELEDEIMBELEDEIMBEMkDEEYQgAI6EQgAEIAEELEDEIMBELEDEIMBOh0IABCABBCxAxCDARCxAxCDARDJAxAEECUQRhCAAjoVCAAQgAQQsQMQgwEQsQMQgwEQBBAlOgkIABCABBAEECU6CAgAEAQQAxAlOgwIABCABBCxAxAEECU6FwgAEIAEELEDEIMBEMkDEAQQJRBGEIACOg8IABCABBCxAxCDARAEECVQ9wpYqz1guewBaAlwAHgAgAH5AYgByRGSAQYxMS43LjKYAQCgAQGwAQo&sclient=gws-wiz",wait_until='networkidle')

    # ---------------------
    context.close()
    browser.close()


with sync_playwright() as playwright:
    run(playwright)


コメントが操作単位に入っているので、初見でも触りやすい
構造が地獄なページを触った場合のlocatorがどうなるかも確認してみたいところ

記録した操作を実行する

pyやpytestで出力したソースを実行するだけ

# 単純なpythonコードとして実行する場合
py .\PlaywrightSample.py

# テストとして実行する場合
pytest .\PlaywrightSample.py

感想

出力されたコードが初見でもわかりやすいことに感動した
先にも触れたが、構造が地獄なページだとどうなるのかが興味ある
セレクターは研究が必要かもしれない
page.wait_for_url()のタイムアウトエラーについて調査していたところ、デフォルトタイムアウトの設定が私の環境では効かないことがわかった(使い方が悪かった?)

使い込んでいけば色々こうしてほしい点は出てくるだろうが、seleniumのようにイチからコードを組むことに敷居の高さを感じる人には良いと思う

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0