概要
python でテストした ISBN 番号から書籍情報検索を C# で行います。C# から Selenium 経由 でWebdriver を操作出来ることを確認しました。
Selenium インストール
今回は、C#のフォームプロジェクトを作成します。
(1)「プロジェクト」-「NuGetパッケージの管理」選択
※インターネットに接続している前提です。
(2)ドライバーインストール
次の①~④の手順でインストールします。
①参照
②検索キーに「Selenium」と入力、検索
③「Selenium.WebDriver」選択
④「インストール」クリック
※インストール時、確認メッセージが表示された
場合は、「OK」をクリックします。
※ 同様に「Selenium.Support」をインストールします。
インストールしたドライバーが、どの操作に有効なのか理解していませんが、別件でテストしたドロップダウンリストの選択に用いる「Select」に 「Selenium.Support」 が必要でした。また、ブラウザーを開く際に、開くまで待つコマンドが、正常に動作する様になった気がします。(曖昧な記憶です)
同様に chrome 等の WebDriver もインストール出来る様ですが、敢えてここではインストールせずに、python で使用したドライバーをそのまま利用することにしました。
プログラム
内容は、python で行った ISBN番号から、書籍情報を取得・表示する処理と同じです。ユーザーインターフェースは下記の通りです。
ブラウザーで書店検索ページを開き、ISBN番号設定、検索ボタンクリック、検索結果を取得する等の途中の過程は、python 処理内容と同じですので、記載は省略します。
プログラムコードは次の通りです。
43行でドライバーを指定していますが、パス指定しなければ、C#の実行ファイルがあるフォルダー内のドライバーファイルを選択してくれる様です。また、指定する場合もフォルダを指定する様です。
一方、ファイル名は予め決まっている様です。chrome の場合はダウンロード・解凍したWebDriver をそのまま使用できましたが、EdgeDriver はエラーが出るので今回はDriver側のファイル名を変更して対応しました。
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using OpenQA.Selenium; using OpenQA.Selenium.Chrome; // using OpenQA.Selenium.Edge; using OpenQA.Selenium.Support; using OpenQA.Selenium.Support.UI; namespace c_sharp_selenium { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { string isbn_no = this.textBox1.Text.Trim().Replace( "-" , "" ) ; if (isbn_no.Length != 13) { MessageBox.Show("ISBN_NO入力異常です。処理を中断します。","ISBN_NO入力異常",MessageBoxButtons.OK,MessageBoxIcon.Error); return; } this.richTextBox1.Text = ""; this.richTextBox2.Text = ""; this.textBox2.Text = ""; System.Windows.Forms.Application.DoEvents(); // ChromeDriverを実行ファイルと同フォルダに配置 // 異なる場合は格納フォルダまでのパス設定→例 @"C:\Users\<省略>\c_sharp_selenium\bin\Debug" IWebDriver driver = new ChromeDriver(); try { driver.Navigate().GoToUrl("〈省略:書店検索URL〉"); bool pop_up_auth = false; if (pop_up_auth) { // PROXY-SERVER POP-UP認証設定例 Thread.Sleep(200); SendKeys.Send("USER_NAME"); // ユーザー名 SendKeys.Send("{TAB}"); SendKeys.Send("USER_PASS"); // パスワード Thread.Sleep(100); SendKeys.Send("{ENTER}"); } } catch { MessageBox.Show("検索時間を超過しました。処理を中断します。", "検索時間超過", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } driver.FindElement(By.XPath("//*[@id='〈省略〉']/form/dl/dd[1]/input")).SendKeys(isbn_no.ToString().Trim()); driver.FindElement(By.Id("〈省略〉")).Click(); try { Thread.Sleep(3500); WebDriverWait wait = new WebDriverWait(driver, new TimeSpan(0, 0, 30)); wait.Until(drv=>drv.FindElement(By.Id("〈省略〉"))); } catch{ MessageBox.Show("検索結果を開くのに失敗しました。処理を中断します。", "検索結果開示失敗", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } string bk_info1 = driver.FindElement(By.XPath("//*[@id='〈省略〉']/form/div[1]/div/div[2]/h3/a")).Text ; string bk_info2 = driver.FindElement(By.XPath("//*[@id='〈省略〉']/form/div[1]/div/div[2]/div[2]/p")).Text; string bk_info3 = driver.FindElement(By.XPath("//*[@id='〈省略〉']/form/div[1]/div/div[2]/div[3]/ul/li/span")).Text; this.richTextBox1.Text = bk_info1; this.richTextBox2.Text = bk_info2; this.textBox2.Text = bk_info3; System.Windows.Forms.Application.DoEvents(); // MessageBox.Show("検索終了", "検索終了", MessageBoxButtons.OK, MessageBoxIcon.Information); driver.Quit(); } } }
【Proxy-Server 認証対応】
51~57 行目は、proxy-server 認証が必要な場合の自動化時に利用できる方法です。ドライバー指定時のオプション等のスマートな設定方法を調べましたが、良い方法が見つかりませんでした。結果的にはこの方法で目的は達成できました。
認証自動化是非に対する考え方もありますが、ここにたどり着くのにいろいろ調べたので、忘れない様にプログラム内に残しておきます。
【ポップアップアラート対応】
今回は使用していませんが、ブラウザ操作中にポップアップアラート(※処理の継続/中断を確認するメッセージボックス)を表示するサイトがあります。この場合、Selenium から要素として見つけることができませんが、C#では次の通り対応可能です。
Dim chrome As New ChromeDriver
chrome.SwitchToAlert.Accept() ’ OK
chrome.SwitchToAlert.Dismiss() ‘ キャンセル
Dim dspMsg As String = chrome.SwitchToAlert.Text ‘ 表示文字取得
参考までに、Python では次の通りです。
・Alert(driver).accept() ’ OK
・Alert(driver).dismiss() ‘ キャンセル
・ Alert(driver).text ‘ 文字列取得
まとめ
基本Windows環境で利用するので、C#でプログラム作成出来る利点は大きいです。