目的
Seleniumを使ったConsoleApplicationの環境構築メモ。
RPAっぽいことをするためのことはじめ。
準備
Nugetでインストールするもの
- Microsoft.Extensions.DependencyInjection
- Dependency Injectionをするためにインストール。
- v5.0.2を利用
- Microsoft.Extensions.Hosting
- Dependency Injectionをするためにインストール。
- v5.0.0を利用
- Selenium.WebDriver
- Seleniumを動かすためにインストール。
- v3.141.0を利用。
- Selenium.WebDriver.ChromeDriver
- Chromeを利用してWeb Appを動かすためにインストール。
- v92.0.4515.4300を利用。
そのほか
ターゲットフレームワークは、.NET 5.0を選択。
Helloworld
Seleniumのサイトのサンプルコードを使って動作確認。
class Program { public Program() { } static void Main(string[] args) { Host.CreateDefaultBuilder(args) .ConfigureServices((context, services) => { services.AddTransient<Program>(); }) .Build().Services .GetRequiredService<Program>() .Run(args); } public void Run(string[] args) { Console.WriteLine("Hello"); using (var driver = new ChromeDriver(".")) { //Navigate to DotNet website driver.Navigate().GoToUrl("https://dotnet.microsoft.com/"); //Click the Get Started button driver.FindElement(By.LinkText("Get Started")).Click(); // Get Started section is a multi-step wizard // The following sections will find the visible next step button until there's no next step button left IWebElement nextLink = null; do { nextLink?.Click(); nextLink = driver.FindElements(By.CssSelector(".step:not([style='display:none;']):not([style='display: none;']) .step-select")).FirstOrDefault(); } while (nextLink != null); // on the last step, grab the title of the step wich should be equal to "Next steps" var lastStepTitle = driver.FindElement(By.CssSelector(".step:not([style='display:none;']):not([style='display: none;']) h2")).Text; // verify the title is the expected value "Next steps" Console.WriteLine(lastStepTitle); } } }
Unit Test用のサンプルだったため、最後にAssertの処理があったが、ConsoleWriteLineに変更してコンソールアプリとして動くようにした。
Yahooの乗換案内から、料金を取得する。
public string GetFareOfRoute1(string from, string to) { using (var driver = new ChromeDriver()) { driver.Navigate().GoToUrl("https://transit.yahoo.co.jp/"); var sFrom = driver.FindElement(By.Id("sfrom")); sFrom.Clear(); sFrom.SendKeys(from); sFrom.SendTabKey(); var sTo = driver.SwitchTo().ActiveElement(); sTo.SendKeys(to); var searchModule = driver.FindElement(By.Id("searchModuleSubmit")); searchModule.Click(); searchModule.DelayAction(1000); var fare = driver.FindElement(By.XPath("//*[@id=\"rsltlst\"]/li[1]/dl/dd/ul/li[2]")).Text; return fare; } }
検索結果の表には、IDが指定されていたが、表の中の各項目にはそれらしいIDがなかったため、Xpathを利用して対象のElementを特定し、そこから値を取得するようにした。その他の項目については、IDが指定されていたため、ID経由でアクセスすることができた。
タブキーの送信と、待機処理は後々のことを考えて拡張メソッドとして定義した。キーボード操作はほかにもいろいろあるため、必要に応じてここのメソッドを拡張していこうと思う。
public static class SeleniumDriverExtension { public static void SendTabKey(this IWebElement element) { element.SendKeys("\uE004"); } public static void DelayAction(this IWebElement element, int millisecondsDelay) { Task.Delay(millisecondsDelay).Wait(); } }