C#でWEBブラウザ操作(Selenium プログラミング)

概要

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


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です