Go(navigator)でブラウザ操作(テスト自動化など)

テストなどで、プログラムでブラウザを操作できないかなぁ・・・ というときに使うのが Selenium です。 で、これを Go で扱うためのパッケージとして、Agoutiがあります。

しかしながら、もうメンテナンスされていない模様。。。 ということで、navigatorを使ってみました。 下記は、このブログに対してゴニョゴニョやってみた例です。

package main

import (
    "context"
    "fmt"
    "github.com/ikawaha/navigator"
    "os"
    "time"
)

func main() {
    if err := run(); err != nil {
        fmt.Println(err)
        os.Exit(1)
    }
}

func run() error {
    driver := navigator.ChromeDriver(navigator.Browser("chrome"), navigator.Debug)
    defer driver.Stop()

    ctx := context.Background()
    if err := driver.Start(ctx); err != nil {
        return fmt.Errorf("driver.Start() failed: %w", err)
    }

    page, err := driver.NewPage()
    if err != nil {
        return fmt.Errorf("driver.NewPage() failed: %w", err)
    }

    // ブログトップを開く
    page.Navigate("https://yumgoo17.hatenablog.com/")

    // 検索ボックスに TensorFlow と入力
    if err := page.FindByName("q").Fill("TensorFlow"); err != nil {
        return err
    }

    // 検索実行(サブミット)
    if err := page.FindByClass("search-module-button").Submit(); err != nil {
        return err
    }

    // あるブログ記事を開く
    page.Navigate("https://yumgoo17.hatenablog.com/entry/2023/05/10/Go_%E3%81%AE%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%83%BB%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%95%E3%82%A7%E3%83%BC%E3%82%B9%E5%91%A8%E3%82%8A%E8%A6%9A%E6%9B%B8%E3%81%8D")

    // 「コメントを書く」をクリック
    if err := page.FindByClass("leave-comment-title").Click(); err != nil {
        return err
    }

    // 新しく開いたウィンドウにフォーカスする
    if err := page.NextWindow(); err != nil {
        return err
    }

    // 表示されるまでちょっと待つ
    time.Sleep(1 * time.Second)

    // 投稿者・URL・メール・コメントを入力
    if err := page.FindByID("name").Fill("テスト太郎"); err != nil {
        return err
    }
    if err := page.FindByID("url").Fill("https://test.example.test.com"); err != nil {
        return err
    }
    if err := page.FindByID("mail").Fill("test@test.example.test.com"); err != nil {
        return err
    }
    if err := page.FindByID("body").Fill("テストコメント"); err != nil {
        return err
    }

    // reCAPTCHA は対応できず

    // Submit
    //if err := page.FindByID("submit").Submit(); err != nil {
    // return err
    //}

    time.Sleep(2 * time.Second)

    return nil
}

上記ソースや、navigatorのREADMEを見てもらってもわかると思いますが、とてもわかりやすく簡単に使えますね。

このブログにコメントしようとすると、ログインしてないときは reCAPTCHA が必要なようですが、当然のことながら、それは突破できませんでした。