Playwrightのcodegenを使ってみた|操作を記録してブログ検索を自動化

前回は、Playwrightで自分のブログを開き、記事タイトルとURLをCSVに保存してみました。

今回は、前回の最後に予告した codegen を試してみます。ブラウザで行った操作から、コードを自動生成してくれる機能です。

私は以前、Seleniumでブラウザ操作を自動化しようとして、待ち時間の調整などで苦労したことがありました。その経験もあって、Playwrightを触りながら、操作を書きやすいことや自動待機の便利さを感じています。

そんな中で試したcodegenですが、これが思っていた以上に面白かったんです。

自分でリンクをクリックすると、その操作がコードになる。文字を入力すると、その文字もコードに入る。さらに、生成されたコードを少し変えれば、別の言葉で検索できる。

操作を記録して終わりではなく、自分の用途に合わせて使える。

今回は、その感覚がつかめるところまで、小さく試してみます。私自身も学んでいる途中なので、実際に動かしながら一つずつ進めていきます。

目次

今回作るもの:言葉を入力するとブログを自動検索

今回の題材は、自分のブログ内を検索する操作です。

完成すると、次のように動きます。

  1. プログラムを実行すると、ターミナルで検索したい言葉を聞かれる。
  2. PythonExcel などを入力して、Enterを押す。
  3. ブラウザが自動で開き、ブログの検索欄にその言葉が入力される。
  4. 検索が実行され、結果が表示される。

もちろん、ブログを検索するだけなら手で操作してもできます。

今回は、その身近な操作を使って、「記録したコードを動かす」「一部を変える」「入力した言葉で使う」という、自動化の基本を体験するのが目的です。

最初から完成版を作るのではなく、まずは自分の検索操作を記録するところから始めましょう。

codegenでブラウザ操作を記録してみる

まずは、ブログで検索する操作を記録します。

今回は、前回の記事で作った作業フォルダと仮想環境をそのまま使います。前回と同じ場所に作成した場合は、PowerShellで次のコマンドを順に実行してください。

PowerShell
cd C:\dev\playwright-study
.\.venv\Scripts\Activate.ps1

行の先頭に (.venv) と表示されれば、準備できています。すでにこのフォルダで仮想環境を有効にしている場合は、そのまま次へ進めます。

続いて、codegenを起動します。

PowerShell
playwright codegen https://jiijisanpo.com/

すると、2つの画面が開きます。

ブラウザ:ブログを表示し、自分で操作する画面。
Playwright Inspector:操作から生成されたコードを見る画面。

これから操作するのは、codegenで開いたブラウザです。普段使っているブラウザとは別なので、ここだけ気をつけてください。

ブログで「python」を検索する

開いたブログで、次の操作を行います。

  1. ページ上部にある虫眼鏡の検索ボタンをクリックする。
  2. 検索欄に python と入力する。
  3. 検索を実行するボタンをクリックする。

操作しながら、Inspectorのコードも見てみてください。

クリックするとクリックの命令が追加され、文字を入力すると、入力した言葉がコードに反映されます。

私が面白いと感じたのは、この部分でした。自分で行った操作が、その場でPythonの書き方になっていきます。

まだコード全体を理解できなくても大丈夫です。まずは、自分の操作に合わせてコードが変わる様子を確認してみてください。

検索結果が表示されたら、Inspector上部の「Record」をクリックして記録を止めます。続いて、紙が2枚重なったコピーのアイコンを押し、生成されたコード全体をコピーしておきます。

次は、そのコードの中から、自分が行った検索操作を探してみます。

自分の操作が、どんなコードになったか見てみる

検索操作を記録すると、InspectorにはPythonのコードが表示されます。

最初は、思ったより長いコードに見えるかもしれません。私も、まずどこを見ればよいのか確認しながら進めました。

記録されたコードには、検索欄をクリックする操作も含まれています。ここでは、検索の流れが分かる次の3行に注目します。

Python
page.locator("#header").get_by_role("button", name="検索").click()
page.get_by_role("textbox", name="検索ワード").fill("python")
page.get_by_role("button", name="検索を実行する").click()

順番に読むと、ブラウザで自分が行った操作と対応しています。

自分が行った操作コードの意味
ヘッダーの虫眼鏡をクリックしたヘッダー内の「検索」というボタンを探してクリック
検索欄に python と入力した「検索ワード」という入力欄に文字を入れる
検索を実行した「検索を実行する」というボタンをクリック

「どこを操作するか」と「何をするか」に分けて読む

例えば、文字を入力した部分です。

Python
page.get_by_role("textbox", name="検索ワード").fill("python")

少し長く見えますが、次のように分けられます。

  • page:今操作しているページ。
  • get_by_role("textbox", name="検索ワード"):「検索ワード」という名前の入力欄を探す。
  • .fill("python"):その入力欄に python と入れる。

つまり、「このページの、どの入力欄に、何を入れるか」が書かれています。

また、最初の行にある locator("#header") は、対象をヘッダー内に絞る指定です。#header は、HTMLの idheader の要素を表します。

同じページに検索ボタンが複数あっても、どこのボタンを操作するのかを絞れます。

クリックすると、指定の書き方も分かる

前回の記事では、記事URLを取得する際に、HTMLの親子関係を調べました。

今回は、自分で操作すると、その対象を指定するコードが生成されます。

「この入力欄をPythonでどう指定したらよいのだろう?」

そう思ったときに、まずcodegenで操作して、生成された書き方を見てみる。そんな使い方もできそうだと感じました。

なお、生成される指定は、ページの構造や操作した場所などによって変わることがあります。ここに載せたコードと文字が完全に同じでなくても、まずは自分の操作と対応しているかを見てください。

今は、すべての書き方を覚えなくても大丈夫です。

まずは、クリックが .click()、文字の入力が .fill() になっていることを確認できれば、一歩前進です。

次は、記録したコードを実行して、同じ検索操作が再現されるか試してみます。

記録したコードを動かしてみる

ここまでで、自分が行った検索操作をコードにできました。

今度は、そのコードを実行してみます。先ほどは自分でクリックしましたが、今回はPythonに同じ操作を任せます。

動きを確認できるように少し整える

生成されたコードを見ると、最後にブラウザを閉じる処理が入っています。そのまま実行すると、検索後にブラウザが閉じてしまい、結果を見逃しそうです。

そこで、観察しやすいように2つ追加します。

  • slow_mo=1000:操作をゆっくり見せる。
  • input():Enterを押すまで終了処理へ進まず、結果を見る時間を確保する。

ここでの slow_mo は、動きを人間が見やすくする設定です。ページが操作できる状態になるまで待つ「自動待機」とは、役割が違います。

以下は、記録したコードにこの2つを加え、今回使わないインポートを省いたものです。

search_demo.pyに保存する

前回と同じ作業フォルダに search_demo.py を作り、次のコードを貼り付けて保存します。

Python
from playwright.sync_api import Playwright, sync_playwright


def run(playwright: Playwright) -> None:
    # ブラウザを起動し、操作をゆっくり見せる
    browser = playwright.chromium.launch(
        headless=False,
        slow_mo=1000
    )

    context = browser.new_context()
    page = context.new_page()

    # ブログを開く
    page.goto("https://jiijisanpo.com/")

    # ヘッダーの検索ボタンをクリック
    page.locator("#header").get_by_role(
        "button", name="検索"
    ).click()

    # 検索欄に文字を入力
    page.get_by_role(
        "textbox", name="検索ワード"
    ).fill("python")

    # 検索を実行
    page.get_by_role(
        "button", name="検索を実行する"
    ).click()

    # 結果を見る時間を確保する
    input("確認できたら、ここでEnterを押してください:")

    context.close()
    browser.close()


with sync_playwright() as playwright:
    run(playwright)

検索操作の3行は、読みやすいように改行していますが、記録した内容と同じです。自分の環境で別の指定が生成された場合は、その部分を記録したコードに合わせてください。

マウスに触らず、動きを見てみる

記録用のInspectorとブラウザを閉じます。

仮想環境が有効なPowerShellで、次を実行してください。

PowerShell
python search_demo.py

今度は、マウスに触れずに見てみます。

ブラウザが開き、ブログが表示されます。続いて検索画面が開き、python と入力され、検索が実行されます。

先ほど自分で行った操作が、順番に再現されれば成功です。

結果を確認したら、PowerShellに戻り、Enterを押してください。ブラウザが閉じ、プログラムが終了します。

自分の操作を記録し、そのコードで同じ操作を再現できました。

次は、コードの一部を変えて、別の言葉でも検索できるか試してみます。

検索する言葉を変えてみる

記録した操作を再現できたので、今度は検索する言葉を変えてみます。

先ほど保存した search_demo.py の中から、次の部分を探してください。

Python
    # 検索欄に文字を入力
    page.get_by_role(
        "textbox", name="検索ワード"
    ).fill("python")

この "python""Excel" に変更します。

Python
    # 検索欄に文字を入力
    page.get_by_role(
        "textbox", name="検索ワード"
    ).fill("Excel")

変更するのは、引用符の中の言葉だけです。検索欄を開いたり、検索ボタンを押したりする部分は、そのまま使います。

ファイルを保存して、PowerShellでもう一度実行します。

PowerShell
python search_demo.py

ブラウザが開き、今度は検索欄に Excel と入力されます。その言葉で検索されれば成功です。

検索結果が0件でも、指定した言葉で検索できていれば、操作自体はうまく動いています。

記録した操作を、別の検索にも使えた

codegenで記録したときに入力したのは、python でした。でも、コードの中の言葉を変えると、Excel でも検索できました。

別の検索語を使うために、最初から操作を記録し直す必要はなかったわけです。

私は、このあたりからcodegenの使い道が見えてきました。

操作を記録して、同じことを繰り返す。さらに、変えたい部分を少し直して、自分の用途に合わせて使う。

生成されたコードを読んでみる意味も、ここにあると感じます。

ただ、検索するたびにファイルを開いて、言葉を書き換えるのは少し手間です。

次は、プログラムを実行するときに検索語を入力できるようにしてみます。

毎回コードを書き換えずに検索できるようにする

そこで最後に、プログラムを実行したときに、検索したい言葉を入力できるようにします。

入力された言葉を変数で受け取る

まず、インポート文の下、def run(...) より上に、次の1行を追加します。

Python
SEARCH_WORD = input("検索したい言葉を入力してください:")

input() は、入力を待ち、Enterが押されたら、入力された文字列を返します。

その文字列を受け取っておくのが、SEARCH_WORD という変数です。ここに、今回検索したい言葉が入ります。

次に、検索欄へ文字を入れる部分を変更します。

Python
    ).fill("Excel")

これを、次のようにします。

Python
    ).fill(SEARCH_WORD)

今度は SEARCH_WORD を引用符で囲みません。変数に入っている言葉を使うためです。

これで、ターミナルで入力した言葉を、ブラウザの検索欄へ渡せるようになりました。

完成版のコード

ここまでの変更をまとめたコードです。search_demo.py を次の内容にして保存します。

Python
from playwright.sync_api import Playwright, sync_playwright


# 実行時に、検索したい言葉を受け取る
SEARCH_WORD = input("検索したい言葉を入力してください:")


def run(playwright: Playwright) -> None:
    # ブラウザを起動し、操作をゆっくり見せる
    browser = playwright.chromium.launch(
        headless=False,
        slow_mo=1000
    )

    context = browser.new_context()
    page = context.new_page()

    # ブログを開く
    page.goto("https://jiijisanpo.com/")

    # ヘッダーの検索ボタンをクリック
    page.locator("#header").get_by_role(
        "button", name="検索"
    ).click()

    # ターミナルで受け取った言葉を検索欄に入力
    page.get_by_role(
        "textbox", name="検索ワード"
    ).fill(SEARCH_WORD)

    # 検索を実行
    page.get_by_role(
        "button", name="検索を実行する"
    ).click()

    # 結果を見る時間を確保する
    input("確認できたら、ここでEnterを押してください:")

    context.close()
    browser.close()


with sync_playwright() as playwright:
    run(playwright)

好きな言葉を入力して試してみる

仮想環境が有効なPowerShellで実行します。

PowerShell
python search_demo.py

今度は、すぐにはブラウザが開きません。先にPowerShellに次の案内が表示されます。

PowerShell
検索したい言葉を入力してください:

ここに PythonExcelSelenium などを入力し、Enterを押してください。

PowerShellで検索語「Excel」を入力。Enterを押すとブラウザが動き始めます。

するとブラウザが起動し、入力した言葉でブログを検索します。結果を確認したら、PowerShellに戻り、もう一度Enterを押して終了します。

入力した「Excel」でブログを自動検索。検索結果が表示されました。

コードには input() が2か所ありますが、役割はそれぞれ違います。

場所役割
最初の input()検索する言葉を受け取る
最後の input()結果を確認するまで終了を待つ

別の言葉を検索したいときは、同じプログラムをもう一度実行して、入力する言葉を変えるだけです。

これで、毎回コードを編集せずに使えるようになりました。

最初は、ブログを手で操作して記録しただけでした。そこから少しずつ変更して、入力した言葉で動く小さな道具になりました。

今回は、ここまでを完成とします。

Seleniumで苦労した私が、今回感じたこと

私は以前、Seleniumでブラウザ操作を自動化しようとして、待ち時間の調整などで苦労したことがありました。

その経験があるので、Playwrightで操作が順番に進んでいくのを見ると、「これなら、もう少し自分でも扱えそうだ」と感じます。

操作できる状態になるまで待ってくれる

今回便利だと感じたことの一つが、Playwrightの「自動待機」です。

例えば、ボタンをクリックするときには、対象が表示され、操作できる状態かを確認してからクリックしてくれます。

自分で「とりあえず数秒待つ」という処理を挟む手間を減らせるのは、以前そこで苦労した私にはうれしいところでした。

ここは、私自身も整理して理解できた点があります。

今回使った sync_playwright は同期版です。この便利さは、「非同期で動くから」というより、Playwrightに自動待機の仕組みがあるためです。

また、サンプルに加えた slow_mo=1000 は、操作をゆっくり見せるための設定です。自動待機とは役割が違います。

もちろん、画面上の処理がすべて自動待機だけで解決するわけではありません。独自の処理の完了など、必要に応じて待つ条件を指定する場面もあります。

詳しくは、Playwright公式ドキュメントの自動待機の説明も参考にしてください。

Seleniumとの優劣を決めるほど比較できているわけではありませんが、今回触った範囲では、待ち方を自分で細かく調整する負担が軽く感じられました。

codegenは、試してみたら想像以上に面白かった

今回はPlaywrightの学習の続きとしてcodegenを試しましたが、実際に触ると、思っていた以上に便利でした。

クリックや入力をすると、その操作がコードになる。さらに、生成されたコードを読めば、操作した場所をどう指定しているかも分かります。

コードを一から書くときには、「この検索欄をどう指定すればよいのだろう」と迷います。そんなときに、実際に操作して、指定の書き方を確かめられるのは心強いと感じました。

そして、今回いちばん理解が進んだのは、検索語を変更したところです。

記録したコードの一部を変えるだけで、別の検索にも使える。そこに input() を加えれば、実行するたびに好きな言葉を入力できる。

生成されたコードを自分で少しずつ読んで、変えてみることで、使い道が見えてきました。

まだPlaywrightを使いこなせているわけではありません。それでも今回、小さな操作から始めて、自分で使える形まで進められたことは、次も試してみようと思える体験になりました。

Pythonをもう少し体系的に学びたい方へ

ここまで自分で動かしてみて、まだ少し難しいと感じても大丈夫です。独学で続けるのもよいですし、必要に応じて講座や本で補う方法もあります。

今回はPlaywrightcodegenを使いながら、実際にコードを動かして少しずつ理解していきました。

私自身、分からないことを調べながら進めていますが、「Pythonの基礎から順番に学び直したい」「動画を見ながら手を動かしたい」という場合は、オンライン学習サービスを使うのも一つの方法です。

→ Pythonをもう少し体系的に学びたい方へ

まとめ:記録した操作が、小さな道具になった

今回は、Playwrightcodegenを使って、自分のブログで検索する操作を記録しました。

そこから、次の順番で少しずつ進めました。

  1. ブラウザで操作して、コードを生成する。
  2. 生成されたコードを実行して、同じ操作を再現する。
  3. 検索語を書き換えて、別の検索にも使う。
  4. input()で検索語を受け取り、毎回コードを編集せずに使えるようにする。

最初は「操作がコードになるんだ」という驚きでしたが、実際に変更して動かすと、「こうすれば自分の用途に使えるんだ」と理解が進みました。

codegenで作られたコードも、最初からすべて読めなくて大丈夫です。まずは、自分がクリックした場所や入力した文字が、どこに書かれているかを探すところから始められます。

私もまだ学んでいる途中ですが、今回のように小さな目的を決めて動かすと、一つずつ理解を積み重ねられると感じています。

まずは身近なページで操作を一つ記録して、そのコードを動かしてみてください。そこから一か所変えてみると、自動化の使い道が少し見えてくるかもしれません。

おまけ:表示サイズを指定する

ブラウザとInspectorを並べにくいときは、起動時にページの表示サイズを指定できます。

PowerShell
playwright codegen --viewport-size="1280,720" https://jiijisanpo.com/

1280,720 は、表示領域の幅と高さです。記事用のスクリーンショットを同じサイズでそろえたいときにも便利です。

手元にPythonの入門書を1冊置いておくのも便利です

Playwrightを触っていると、変数や関数などPythonの基本的な書き方を確認したくなることがあります。

そんなときに、初心者向けの入門書を1冊手元に置いておくと、基本に戻って確認しやすくなります。


スッキリわかるPython入門 第2版 (スッキリわかる入門シリーズ)

目次