Windows 10

Selenium WebDriverを使用してMicrosoft EdgeとOfficeを連携させる。

この記事はSelenium/Appiumアドベントカレンダー2015の18日目の記事です。


はじめに

Seleniumアドベントカレンダーに乱入するにあたり、まずは簡単に自己紹介をしておきます。

普段は事務として働いているため、テストも開発も無縁なのですが、「自動化・オートメーション」といった言葉は好きなので、WordやExcel等のOffice アプリケーションやWebブラウザーの制御について、このブログでもちょくちょく取り扱っています。

上記の通り、普段はプログラム開発に携わることがないので、会社で使用しているPCにもVisual Studio等の開発環境が入っていません。

そんな事務員の私でも手軽に使える、自動化のための道具が“VBA(Visual Basic for Applications)”です。
これならば、WordやExcelからすぐにエディタを開き、プログラムを組むことができます。

VBAによるWebブラウザーの制御

Webブラウザーの操作をVBAから行う場合(そもそも業務ではブラウザー制御する機会も無いのですが、そこは置いておきます)、鉄板なのが「Internet Explorer(COM)オートメーション」です。

情報量も非常に多く、「CreateObject(“InternetExplorer.Application”)」をキーワードに検索すれば、Microsoftの情報を含めて様々なサイトがヒットします。

ところが、Windows 10ではOSの標準ブラウザーがMicrosoft Edgeに変わり、COMオートメーションがサポートされなくなりました(Edgeではなく引き続きサポートされているIEを使えば済む話ですが、それもここでは置いておきます)。

Microsoft Edge will not support the COM automation interface (InternetExplorer object) that you referred to.

For automation scenarios, our direction is to support of the WebDriver interface that is supported across browsers. WebDriver support is now available in Microsoft Edge on Windows 10 and requires a separate executable that you can download.

To get an idea of capabilities, you can refer to the Microsoft Edge WebDriver status page which will be kept up-to-date with the latest WebDriver commands available.

http://stackoverflow.com/a/31306444 より

それでは、Edge操作の自動化ができないのかというとそうではなく、上記Stack Overflowの回答の通り、「WebDriver」を使うことで、外部からEdgeを操作することができます。

SeleniumBasicによるEdge制御

EdgeはWebDriver経由での操作がサポートされている、ということが分かったところでMicrosoft Edge Dev Blogにある記事「Bringing automated testing to Microsoft Edge through WebDriver」を見てみると、Edgeを操作してページ移動したりキーストロークを送信したりするサンプルコードが載っています。

しかし、載っているコードはC#です。VBAではありません。
Seleniumのダウンロードページを見ても、対応言語の中にVBAは入っていません。

一見すると、VBAからSelenium WebDriverは扱えないように見えるのですが、そこは大丈夫です。
ちゃんとVBA向けのラッパー「SeleniumBasic」(旧Selenium VBA)が用意されています。
v2.0.6.0 でEdgeのWebDriverもサポートし、これを使えばVBAからEdgeを操作することができるはずです。

EdgeとOfficeの連携

今回アドベントカレンダーの記事を書くにあたり、Officeアプリケーション間の連携が取りやすいVBAを活かすため、“ExcelファイルからURLを読み込み、Edgeで巡回した結果をスクリーンショットとしてWordファイルに貼りつける処理”を考えてみました。

SeleniumBasic(Selenium VBA)がMicrosoft Edgeに対応しました。」記事でも書いた通り、VBAによるEdge操作の動作確認もOKです。

・・・しかし、いざコードを走らせてみると、

SeleniumAdventCalendar2015_01

オートメーション エラー!
上記記事とまったく同じコードを走らせたにも関わらず処理を続行できず、SeleniumBasicを再インストールしても同じ状況です。他の環境でも同様のエラーが発生しました。

SeleniumBasicのコードを深く追っていないので、どこでつまづいているのかは分かりませんが、EdgeのアップデートにSeleniumBasic側が追いついていないのかもしれません。
原因は不明ですが、分かることは一つ、

「このままではSeleniumBasicでのEdge操作について記事が書けない」

ということです。
動作確認時の環境を再構築すれば、再びコードを動作させることができるかもしれませんが、OSを一から入れなおすのは非常に面倒です。

SeleniumBasicを諦める

ではどうするか?
もう色々考えるのは面倒くさいので、SeleniumBasicを使わず.NETでコードを書くことにします。

.NETからOffice アプリケーションを操作する方法の一つとしてCOMコンポーネント呼び出し(Interop)がありますが、この方法は結構やっかいです。
ちょっとでもCOMオブジェクトの解放し忘れがあると、プロセスが残り続けてしまいます。

そこで出番となるのが「NetOffice」。
これを使うと、VBAのような手軽さでWordやExcelを.NETから操作することができます。

結局C#でコードを書く

というわけで、書いたコードが下記になります。

/*
 * リストファイル(Excel)にあるURLをEdgeで巡回してスクリーンショットを撮り、
 * Word文書に貼り付ける。
 * 
 * @kinuasa
 * 
 * [要参照]
 * System.Drawing, System.Windows.Forms,
 * NetOffice(NetOffice.dll),
 * ExcelApi(ExcelApi.dll),
 * WordApi(WordApi.dll),
 * WebDriver(WebDriver.dll),
 * WebDriver.Support(WebDriver.Support.dll)
 */
using System;
using System.IO;
using System.Drawing;
using System.Windows.Forms;
using Excel = NetOffice.ExcelApi;
using Word = NetOffice.WordApi;
using OpenQA.Selenium;
using OpenQA.Selenium.Edge;
using OpenQA.Selenium.Support.UI;

namespace SampleApp
{
  class Program
  {
    [STAThread]
    public static void Main(string[] args)
    {
      //Excel処理
      Excel.Application appEx = new Excel.Application();
      appEx.Visible = true;
      Excel.Workbook wbMain = appEx.Workbooks.Open(@"C:\Test\Urls.xlsx");
      Excel.Worksheet wsMain = (Excel.Worksheet)wbMain.Worksheets[1];
      
      //Word処理
      Word.Application appWd = new Word.Application();
      appWd.Visible = true;
      Word.Document docMain = (Word.Document)appWd.Documents.Add();
      Word.Table tblMain = docMain.Tables.Add(docMain.Range(), 1, 2);
      tblMain.Cell(1, 1).Range.Text = "URL";
      tblMain.Cell(1, 2).Range.Text = "ScreenShot";
      Word.Row rowTbl = null;
      
      //Edge処理
      const string folderName = "Microsoft Web Driver";
      string serverPath = System.IO.Path.Combine(
        System.Environment.GetFolderPath(
          System.Environment.SpecialFolder.ProgramFilesX86
        ), folderName
      );
      EdgeDriver driver = new EdgeDriver(serverPath);
      WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
      
      foreach (Excel.Range rng in wsMain.UsedRange) {
        driver.Navigate().GoToUrl((string)rng.Value);
        wait.Until(x => ((IJavaScriptExecutor)driver).ExecuteScript("return document.readyState").Equals("complete"));
        byte[] ss = ((ITakesScreenshot)driver).GetScreenshot().AsByteArray;
        using (MemoryStream ms = new MemoryStream(ss)) {
          Clipboard.SetImage(Image.FromStream(ms)); //MemoryStreamからImageを作成しクリップボードに格納
        }
        rowTbl = tblMain.Rows.Add();
        rowTbl.Cells[1].Range.Text = (string)rng.Value;
        rowTbl.Cells[2].Range.Paste(); //クリップボードから画像貼り付け
      }
      
      driver.Quit();
      wbMain.Close(false);
      appEx.Quit();
      appEx.Dispose();
      MessageBox.Show("処理が終了しました。");
    }
  }
}

やっつけで書いたのでエラー処理皆無ですが、コードを走らせると一応目的は達成できます。

SeleniumAdventCalendar2015_02

ちなみに、開発環境は「SharpDevelop Portable」を使用しました。

おわりに

当初はSeleniumBasicを使って手軽にVBAからEdge操作を行う方法について記事を書く予定だったのですが、思わぬところで失敗、結局.NET向けのSeleniumを使うことになりました。

他のブラウザー制御でできることがEdgeでできなかったり、Edgeのオートメーションについては、まだまだ不安定なところがあると個人的には感じています。

WebDriverを使わず、UI AutomationやInternet Explorer_Serverクラスのウィンドウを使う方法(起動中のMicrosoft EdgeからタイトルとURLを取得するC#コード(DOM編) 参照)もありますが、そちらも処理が煩雑なので、あまりオススメできません。

とはいっても、Edge自体まだ出始めのブラウザーで、機能もどんどん追加されている段階ですので、SeleniumBasic含めて今後に期待!!…ということで、今回の記事を締めくくりたいと思います。

関連記事

  1. Windows 10

    WebDriverを使わずMicrosoft Edgeを制御するC#コード

    以前書いた記事のように、Microsoft EdgeにはInterne…

  2. Windows関連

    Windows 8 Release PreviewにはMicrosoft Security Esse…

    Windows 8 Release Preview 32ビット版・64…

  3. Windows関連

    [Windows 8]スタートスクリーンの背景色を変更する。

    ※ 下記はWindows Developer Preview(英語版・…

  4. Windows関連

    プリキュア・プリンセスパーティーってWindowsだったの?

    Office 2016だOffice アドインだと記事を書いておきつつ…

  5. Windows 10

    Microsoft Edgeで開いているページを名前を付けて保存する

    2017/4/15 追記:現在この記事に書いてある方法は使えなくな…

  6. Windows関連

    [Windows 8.1]VB5CCEをインストールしてみました。

    ※ 下記はWindows 8.1 RTM(日本語版・32ビット)に基づ…

コメント

  • コメント (0)

  • トラックバックは利用できません。

  1. この記事へのコメントはありません。

Time limit is exhausted. Please reload CAPTCHA.

最近の記事

アーカイブ

RapidSSL_SEAL-90x50
PAGE TOP