基礎から学ぶPython入門 90日コース | Web・API - Day 55:ブラウザ自動化実践

Python 90日で身につけるPython
スポンサーリンク
スポンサーリンク

Day 55:ブラウザ自動化実践 ― 「Web操作自動化ツール」を形にしてみる

Day 55では、ブラウザ自動化の基礎を一歩進めて、 実際に 「Web操作自動化ツール」 を組み立てていきます。

テーマはシンプルですが、やることは少し本格的です。

  • シナリオを決める(どんな操作を自動化するか)
  • ブラウザを起動する
  • ページを表示する
  • 要素を取得する
  • 入力する
  • ボタンを押す
  • 結果を確認する

これらを「ひとつのツール」として、 Pythonコードの中にきれいに並べていくイメージで進めていきます。

Web操作自動化ツールのシナリオを決める

まずは「何を自動化したいか」を言葉にする

ツールを作る前に、 「人間がふだんやっている操作」 を言葉で整理してみます。

例えば、こんなシナリオを考えてみましょう。

  1. ブラウザを開く
  2. 検索サイトを表示する
  3. 検索ボックスにキーワードを入力する
  4. 検索ボタンをクリックする
  5. 結果ページのタイトルをいくつか取得して表示する

この流れをそのままコードにしていけば、 立派な「Web操作自動化ツール」になります。

ここでは、Playwrightを使ってこのシナリオを形にしていきます。

準備:Playwrightの基本セット

Day 54と同じく、Playwrightを使います。

bash

pip install playwright
playwright install

インストールが済んでいる前提で、 コードの中では sync_playwright を使ってブラウザを操作していきます。

ステップ1:ツールの骨組みを作る

「入口」と「メイン処理」を分けて考える

まずは、ツールの骨組みとして、

  • run_web_automation():Web操作自動化のメイン処理
  • main():ツールの入口

という形に分けて書いていきます。

# day55_web_automation_tool.py
from playwright.sync_api import sync_playwright


def run_web_automation():
    """
    Web操作自動化ツールのメイン処理です。
    ここに「ブラウザを開いて → 検索して → 結果を表示する」流れをまとめます。
    """

    # Playwrightのコンテキストを開きます。
    with sync_playwright() as p:
        # ブラウザを起動します(Chromiumを使用)。
        browser = p.chromium.launch(headless=False)

        # 新しいタブ(ページ)を開きます。
        page = browser.new_page()

        # ここから具体的な操作を順番に書いていきます。
        # (後のステップで中身を埋めていきます)

        # 最後にブラウザを閉じます。
        browser.close()


def main():
    """ツールの入口となる関数です。"""
    print("Web操作自動化ツールを開始します。")
    run_web_automation()
    print("Web操作自動化ツールを終了します。")


if __name__ == "__main__":
    main()
Python

この段階ではまだ「何もしない」ツールですが、 骨組みがあることで、これからのステップで中身を埋めやすくなります。

ステップ2:ページ表示と検索ボックスの操作を追加する

検索サイトを開いて、キーワードを入力する

次に、具体的な操作を追加していきます。 ここでは「検索サイトを開いて、キーワードを入力する」流れを作ります。

例として、練習用に「DuckDuckGo」の検索ページを使うイメージで書いてみます。

# day55_web_automation_tool.py
from playwright.sync_api import sync_playwright


def run_web_automation():
    """
    Web操作自動化ツールのメイン処理です。
    - 検索サイトを開く
    - キーワードを入力する
    - 検索ボタンをクリックする
    """

    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        page = browser.new_page()

        # 1. 検索サイトを表示します。
        url = "https://duckduckgo.com/"
        print(f"[OPEN] {url} を表示します。")
        page.goto(url)

        # ページの読み込みが落ち着くまで待ちます。
        page.wait_for_load_state("networkidle")

        # 2. 検索ボックスを取得します。
        # DuckDuckGoでは name="q" の input が検索ボックスです。
        search_box = page.locator("input[name='q']")

        if search_box.count() > 0:
            print("検索ボックスが見つかりました。キーワードを入力します。")
            # キーワードを入力します。
            search_box.first.fill("python web automation")
        else:
            print("検索ボックスが見つかりませんでした。")
            browser.close()
            return

        # 3. 検索ボタンをクリックします。
        # DuckDuckGoでは、検索ボタンは id="search_button_homepage" です。
        search_button = page.locator("#search_button_homepage")

        if search_button.count() > 0:
            print("検索ボタンが見つかりました。クリックします。")
            search_button.first.click()
        else:
            print("検索ボタンが見つかりませんでした。")
            browser.close()
            return

        # 検索結果ページの読み込みを待ちます。
        page.wait_for_load_state("networkidle")

        # ここから先で、結果を取得する処理を追加していきます(次のステップ)。
        browser.close()


def main():
    print("Web操作自動化ツールを開始します。")
    run_web_automation()
    print("Web操作自動化ツールを終了します。")


if __name__ == "__main__":
    main()
Python

ポイント:

  • input[name='q'] のように、name 属性で検索ボックスを指定しています。
  • #search_button_homepage のように、id 属性でボタンを指定しています。
  • 要素が見つからなかった場合は、メッセージを出して終了するようにしています。

ステップ3:検索結果から情報を取得する

検索結果のタイトルをいくつか抜き出して表示する

次に、検索結果ページから タイトルを取得して表示する 処理を追加します。

DuckDuckGoの検索結果では、 タイトル部分に特定のCSSクラスが付いているので、それを使って要素を指定します。

# day55_web_automation_tool.py
from playwright.sync_api import sync_playwright


def run_web_automation():
    """
    Web操作自動化ツールのメイン処理です。
    - 検索サイトを開く
    - キーワードを入力する
    - 検索ボタンをクリックする
    - 検索結果のタイトルを取得して表示する
    """

    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        page = browser.new_page()

        # 1. 検索サイトを表示します。
        url = "https://duckduckgo.com/"
        print(f"[OPEN] {url} を表示します。")
        page.goto(url)
        page.wait_for_load_state("networkidle")

        # 2. 検索ボックスにキーワードを入力します。
        search_box = page.locator("input[name='q']")
        if search_box.count() > 0:
            print("検索ボックスが見つかりました。キーワードを入力します。")
            search_box.first.fill("python web automation")
        else:
            print("検索ボックスが見つかりませんでした。")
            browser.close()
            return

        # 3. 検索ボタンをクリックします。
        search_button = page.locator("#search_button_homepage")
        if search_button.count() > 0:
            print("検索ボタンが見つかりました。クリックします。")
            search_button.first.click()
        else:
            print("検索ボタンが見つかりませんでした。")
            browser.close()
            return

        # 検索結果ページの読み込みを待ちます。
        page.wait_for_load_state("networkidle")

        # 4. 検索結果のタイトルを取得します。
        # DuckDuckGoでは、結果タイトルに ".result__title" などのクラスが付いています。
        result_titles = page.locator(".result__title")

        count = result_titles.count()
        print(f"検索結果のタイトルが {count} 件見つかりました。")

        # 先頭からいくつか表示してみます。
        max_show = min(5, count)
        print("\n=== 検索結果タイトル(上位) ===")
        for i in range(max_show):
            title_text = result_titles.nth(i).text_content()
            print(f"[{i + 1}] {title_text}")

        # 少し待ってからブラウザを閉じます。
        page.wait_for_timeout(3000)
        browser.close()


def main():
    print("Web操作自動化ツールを開始します。")
    run_web_automation()
    print("Web操作自動化ツールを終了します。")


if __name__ == "__main__":
    main()
Python

ポイント:

  • page.locator(".result__title") のように、CSSクラスで検索結果タイトルを指定しています。
  • count() で件数を確認し、nth(i) で i番目の要素を取り出しています。
  • 上位5件だけ表示するようにして、画面が見やすくなるようにしています。

ステップ4:ツールとしての「使いやすさ」を少し整える

キーワードを引数にして、再利用しやすくする

ツールらしくするために、 検索キーワードを関数の引数にして、 いろいろなキーワードで使い回せるようにしてみます。

# day55_web_automation_tool.py
from playwright.sync_api import sync_playwright


def run_web_automation(keyword: str):
    """
    Web操作自動化ツールのメイン処理です。
    引数 keyword に指定したキーワードで検索を行い、結果タイトルを表示します。
    """

    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        page = browser.new_page()

        # 1. 検索サイトを表示します。
        url = "https://duckduckgo.com/"
        print(f"[OPEN] {url} を表示します。")
        page.goto(url)
        page.wait_for_load_state("networkidle")

        # 2. 検索ボックスにキーワードを入力します。
        search_box = page.locator("input[name='q']")
        if search_box.count() > 0:
            print(f"検索ボックスが見つかりました。キーワード '{keyword}' を入力します。")
            search_box.first.fill(keyword)
        else:
            print("検索ボックスが見つかりませんでした。")
            browser.close()
            return

        # 3. 検索ボタンをクリックします。
        search_button = page.locator("#search_button_homepage")
        if search_button.count() > 0:
            print("検索ボタンが見つかりました。クリックします。")
            search_button.first.click()
        else:
            print("検索ボタンが見つかりませんでした。")
            browser.close()
            return

        # 検索結果ページの読み込みを待ちます。
        page.wait_for_load_state("networkidle")

        # 4. 検索結果のタイトルを取得します。
        result_titles = page.locator(".result__title")
        count = result_titles.count()
        print(f"検索結果のタイトルが {count} 件見つかりました。")

        max_show = min(5, count)
        print("\n=== 検索結果タイトル(上位) ===")
        for i in range(max_show):
            title_text = result_titles.nth(i).text_content()
            print(f"[{i + 1}] {title_text}")

        page.wait_for_timeout(3000)
        browser.close()


def main():
    print("Web操作自動化ツールを開始します。")

    # ここで、好きなキーワードを指定できます。
    run_web_automation("python web automation")
    # run_web_automation("業務自動化 python")
    # run_web_automation("ブラウザ自動化 playwright")

    print("Web操作自動化ツールを終了します。")


if __name__ == "__main__":
    main()
Python

こうしておくと、

  • キーワードを変えるだけで、同じツールをいろいろな検索に使える
  • 将来的に「キーワードを外部ファイルから読み込む」などの拡張もしやすい

というメリットが出てきます。

Day 55ミニテンプレート:Web操作自動化ツールの基本形

最後に、Day 55の内容をコンパクトにまとめた 「Web操作自動化ツール」テンプレート を載せておきます。

# day55_web_automation_tool_template.py
from playwright.sync_api import sync_playwright


def run_web_automation(keyword: str):
    """
    Web操作自動化ツールの基本形です。
    - 検索サイトを開く
    - キーワードを入力する
    - 検索ボタンをクリックする
    - 検索結果のタイトルをいくつか表示する
    """

    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        page = browser.new_page()

        # ページ表示
        url = "https://duckduckgo.com/"
        print(f"[OPEN] {url} を表示します。")
        page.goto(url)
        page.wait_for_load_state("networkidle")

        # 要素取得&入力
        search_box = page.locator("input[name='q']")
        if search_box.count() == 0:
            print("検索ボックスが見つかりませんでした。")
            browser.close()
            return

        print(f"キーワード '{keyword}' を入力します。")
        search_box.first.fill(keyword)

        # ボタン操作
        search_button = page.locator("#search_button_homepage")
        if search_button.count() == 0:
            print("検索ボタンが見つかりませんでした。")
            browser.close()
            return

        print("検索ボタンをクリックします。")
        search_button.first.click()

        # 結果ページの読み込み待ち
        page.wait_for_load_state("networkidle")

        # 結果取得
        result_titles = page.locator(".result__title")
        count = result_titles.count()
        print(f"検索結果タイトル数: {count}")

        max_show = min(5, count)
        print("\n=== 検索結果タイトル(上位) ===")
        for i in range(max_show):
            title_text = result_titles.nth(i).text_content()
            print(f"[{i + 1}] {title_text}")

        page.wait_for_timeout(3000)
        browser.close()


def main():
    print("Web操作自動化ツールを開始します。")
    run_web_automation("python web automation")
    print("Web操作自動化ツールを終了します。")


if __name__ == "__main__":
    main()
Python

Day 55のまとめ

Day 55では、ブラウザ自動化の実践として、

  • 「人がブラウザでやっている操作」をシナリオとして言葉にすること
  • Playwrightを使って、ページ表示・要素取得・入力・ボタン操作をひとつの流れにまとめること
  • 検索サイトを例に、キーワード入力→検索→結果取得という一連の操作を自動化すること
  • キーワードを引数にすることで、ツールとして再利用しやすくすること

を、ステップバイステップで整理しました。

ここまで来ると、

  • ログイン処理の自動化
  • 管理画面の定型操作の自動化
  • 社内Webツールの操作の自動化

など、より実務に近い「Web操作自動化ツール」へと、 自然に発展させていけるようになります。

タイトルとURLをコピーしました