Selenium + WebDriverをさわる

Seleniumを使った開発のイメージ

先日から空き時間を見つけてちょこちょこと作っているツール、FSharp.DataのHttpクライアントを使ったPOST処理では、外部からの不正なリクエストとみなされてしまう状況が改善しないようなので、WebDriver + Seleniumを使ってアクセスをしてみることにしました。

そこで、まずはSeleniumの使い方を調べます。

Microsoft Edge は Selenium 向けのドライバを用意してくれていて、これを利用するのが良さそうです。チュートリアルページには(少し古いのでそのままでは動きませんでしたが)Bing にリクエストを送る簡単なサンプルがあったので、それを基にして、検索結果のページのタイトル一覧を取るプログラムを書いてみました。

EdgeのWebDriverをダウンロードする

こちらのページから自分の環境に合ったものをダウンロードしてきます。
(今回は、C\bin\WebDriver配下に配置しました。)

プロジェクトを作成して、Seleniumを使えるようにする

コンソールプログラムで作るので、コンソールのプロジェクトを作っておいてから、Selenium.WebDriver をプロジェクトに追加します。

dotnet new console -lang F# 
dotnet add package Selenium.WebDriver

Bingにリクエストを送って、検索結果ページのタイトル一覧を列挙する

open OpenQA.Selenium
open OpenQA.Selenium.Edge

let driverPath = @"C:\bin\WebDriver"
let service = EdgeDriverService.CreateDefaultService driverPath

// ヘッドレスモードで起動
let option = new EdgeOptions()
option.AddArgument("headless")

let driver = new EdgeDriver(service, option)

try
    driver.Url <- "https://bing.com"
    System.Threading.Thread.Sleep(3000)
    let input = driver.FindElement(By.Id("sb_form_q"))
    input.SendKeys("Microsoft Docs F#")
    input.Submit()

    System.Threading.Thread.Sleep(3000)

    //検索ページのタイトルを取得してコンソールに表示
    driver
        .FindElement(By.Id("b_results"))
        .FindElements(By.CssSelector("li[class='b_algo']"))
    |> Seq.iter (fun e -> printfn $"""{e.FindElement(By.TagName("h2")).Text}""")

finally
    driver.Quit()

ほとんどC#で書かれているチュートリアルページのコードそのままですが、いまのところのBingの作りでは、(多少のエラーはでるものの)これで期待している動きを実現できそうです。

ミソはUrlを代入した後のスリープ(Webページが読み込まれるまで待つ感じ)と、Submit後のスリープかなと思います。(どちらも無いと、ネットワークアクセスが早すぎてすぐ終わってしまいます。)

一旦、これでWebフォームへのアクセス手段を手に入れたので、ぼちぼちツールへの適用を進めていこうと思います。