概要
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#でプログラム作成出来る利点は大きいです。