UWSC + SeleniumVBAでChromeやFirefoxを自動操作する

SeleniumVBAは今後更新されません!SeleniumBasicと名を変えてGitHubで公開されています
SeleniumVBAはSeleniumBasicになってました に導入方法なんかを書きましたので、そちらを御覧くださいな


前回は非常にさっくりだったので、今回は InternetExplorer.Application と比べながら簡単な使い方を紹介する感じの記事です

準備

何はともあれ先ずはSeleniumVBAをインストールしましょう
https://code.google.com/p/selenium-vba/#Download

インストーラに従ってちょちょいとインストールしてください
あとは、Firefoxを操作したい場合はSelenium IDEアドオンをFirefoxにインストール
IEを操作したい場合はインターネットオプションのセキュリティタブで、「インターネット」「ローカルイントラネット」「信頼済みサイト」「制限付きサイト」のすべての保護モードをオンまたはオフで統一しといてください (オンオフがバラバラだとエラーで動きません)

実践

オブジェクトの作成

さて、準備ができたら実際に動かしてみましょうね
最初にWebDriverオブジェクトを作成します

// InternetExplorer.Application
ie = createoleobj("InternetExplorer.Application")

に相当する部分ですね

// SeleniumWrapper.WebDriver
driver = createoleobj("SeleniumWrapper.WebDriver")
driver.start("chrome")

これでChromeが起動します
start()に渡す引数でブラウザを指定します、firefox ie ie64 safari phantomjs
また、第2引数で最初に開いておくページも指定できます

// SeleniumWrapper.WebDriver
driver.start("chrome", "http://www.uwsc.info/")

ページの遷移

// InternetExplorer.Application
ie.navigate(uri)

相当の動作です

// SeleniumWrapper.WebDriver
driver.open(uri)
// または
driver.get(uri)

opengetの違いって何かあるのかしら…
どっちも指定したuriに移動します
ちなみに、絶対パスでも相対パスでも指定出来ます

// SeleniumWrapper.WebDriver
driver.start("chrome", "http://www.uwsc.info/") // 初期ページをUWSC公式に
// 相対パスで指定
driver.get("/download.html") // http://www.uwsc.info/download.html へ移動

// 絶対パスで指定
driver.open("https://google.com")

ページのロード待ち

// InternetExplorer.Application
BusyWait(ie)

ですね

基本的にはBusyWaitのようにその都度待機用関数を書く必要はないです
driver.start()した後に以下の一行を書き加えておきましょう (一度呼ぶだけで良いです)

// SeleniumWrapper.WebDriver
driver.setImplicitWait(10000) // 最大10秒待つ

待ち時間の指定はミリ秒です
これで、ページロードが発生する度に勝手に待機してくれます

あとは、WebDriverWaitを使った待機方法もあるんですが…あるはずなんですが…
なんか思ってたのと違うな…

// SeleniumWrapper.WebDriver
waiter = createoleobj("SeleniumWrapper.Waiter")
while waiter.Until(条件式, タイムアウトメッセージ)
    sleep(0.1)
wend
// 条件式がtrueを返すまでループする
// これ単にUntil()が !条件式 を返してるだけっぽいのでrepeat-until 条件式 でも良いんじゃ…
// ただ、タイムアウトメッセージというのがあるのでそこが使いようでしょうか

こっちはページロードよりもjsで動的にページが更新される場合に使う感じですかね

追記:
driver.waitFor**()ってのがたくさんありますね、これ使ったほうが良さそうね

PS> $(New-Object -ComObject SeleniumWrapper.WebDriver | Get-Member -Name waitfor*).count
116

なこ
にん

エレメントの取得

// InternetExplorer.Application
ie.document.getElementById(id)
ie.document.getElementsByName(name)
ie.document.getElementsByTagName(tag)
ie.document.querySelectorAll(selector)

こういうやつですね

// SeleniumWrapper.WebDriver
element = driver.findElementById("id")
element = driver.findElementByName("name")
element = driver.findElementByTagName("input")
element = driver.findElementByCssSelector("input[type=<#DBL>button<#DBL>]")
// リンク文字で探す IELINKみたいな感じ、大文字小文字を区別するのに注意
element = driver.findElementByLinkText("text") // 完全一致
element = driver.findElementsByPartialLinkText("text") // 部分一致

findElementBy**は最初に見つかった要素だけを返します
findElementsBy**とすることで該当する要素のコレクションを取得出来ます

// SeleniumWrapper.WebDriver
elements = driver.findElementsByTagName("a")
for element in elements
    print element.getAttribute('href') // リンクのhref属性を表示
next

クリックする

// SeleniumWrapper.WebDriver
element = driver.findElementById("id")
element.click()

文字を入力する

input[type=”file”] にも使えます (ファイル選択ダイアログを勝手に処理してくれます)

// SeleniumWrapper.WebDriver
element = driver.findElementByCssSelector("input[type=<#DBL>text<#DBL>]")
element.sendkeys("hello selenium!")

element = driver.findElementByCssSelector("input[type=<#DBL>file<#DBL>]")
element.sendkeys("C:\hello.txt")

値を空にする

// SeleniumWrapper.WebDriver
element = driver.findElementByCssSelector("input[type=<#DBL>text<#DBL>]")
element.clear()

エレメントの属性値を取得

// SeleniumWrapper.WebDriver
element = driver.findElementByTagName("input")
element.getAttribute("value") // inputタグのvalue値を取得

setAttributeってのは存在しないのです、残念です

現在のURLを取得

// InternetExplorer.Application
ie.document.URL
ie.Document.location.href
ie.LocationURL

とかなんか色々ありましたが

// SeleniumWrapper.WebDriver
driver.Url

でOK

ブラウザを閉じる

// InternetExplorer.Application
ie.quit()

みたいなの

// SeleniumWrapper.WebDriver
driver.stop()
// または
driver.close()

これもなんか違いがあったような気がしたんですが、なんだっけな
まぁでもどっちでも終了しますよ

おまけ: JavaScriptを実行する

時々WebDriverWebElementのメソッドではやりたいことが出来なかったりするので、jsを実行しちゃおうというあれです、最終手段です

// SeleniumWrapper.WebDriver
// 対象エレメントを非表示にする
elem = driver.findElementById("id")
args = safearray(0, 1)
args[0] = elem
args[1] = "none"
driver.executeScript("arguments[0].style.display = arguments[1]", args)

executeScript()の第一引数には実行するスクリプト
第二引数にはスクリプトに渡す引数を配列で渡します
この配列がスクリプト中の配列argumentsにそのまま突っ込まれます
渡す配列はSareArrayにしてください、dim宣言した通常の配列はNG

なんで最終手段なのかというと、せっかくSeleniumが吸収してくれてるブラウザ間の差異を気にしないといけなくなるからです
任せられるところはなるべくSeleniumに任せましょう

広告

UWSC + SeleniumVBAでChromeやFirefoxを自動操作する」への20件のフィードバック

  1. 自分がまさに探していた情報でした!
    ありがとうございますm(__)m

    driver = createoleobj(“SeleniumWrapper.WebDriver”)
    driver.start(“chrome”,”http://yahoo.co.jp/”)

    上記コードを起動してみたところ、
    choromeのURL欄に「data:,」と表示された白紙ページが表示されました。

    win7,64bit環境です。
    SeleniumVBAは最新のものを入れています。
    Program Files、Program Files(x86)どちらでも試してみましたが
    結果は同じでした。

    原因は分かりませんでしょうか?
    お忙しいと思いますが、ご回答いただけると幸いです。
    よろしくお願い致します。

    • それで正常です
      driver.startではWebDriverの起動とベースとなるURLを登録しているだけで、画面遷移などは行われません
      続けて
      driver.get(“/”)
      とすればhttp://yahoo.co.jp/が開かれます

      • ご返信ありがとうございます。
        これで正常だったのですね。
        失礼いたしました。

  2. はじめまして、お世話になっております。
    seleniumVBAでUAいじった上でブラウザ操作することってできますか?
    お暇なときで結構ですので、よろしくお願いします。

    • Webdriverによっては出来るようですね、下記リンクによるとChrome、Firefox、PhantomJSはUAを変更出来そうです
      IEのWebdriverはだめっぽいですが
      http://yizeng.me/2013/08/10/set-user-agent-using-selenium-webdriver-c-and-ruby/
      SeleniumVBAの場合は…ChromeならWebDriver.addArgument()、FirefoxならWebDriver.setPreference()ですかね
      リンク先のサンプルのようにコンストラクタに引数を渡すということは出来ないので、WebDriverのインスタンスを作ってから上記メソッドで必要な値をセットし、WebDriver.start()すればいいんじゃないかと思います
      各メソッドの詳細はSeleniumVBAのヘルプファイルを見て下さい (プログラムメニューにヘルプのショートカットがあります

      • ありがとうございました。
        お手数をおかけしました。

  3. はじめまして、一と申します。

    Seleniumについて調べていたら、
    貴サイトにたどり着きました。

    いままでは、EXCEL VBA でプログラムを組んでいましたが、
    Seleniumの機能を知り、驚いています。

    Seleniumについて、詳しく説明されている、
    貴サイトに出会えて幸せです。
    いまから、いろいろと読ませていただきたいと思います。

    さっそくですが、Selenium初心者につき、
    もし宜しければ、2つほど、質問させていただきたいのですが、

    ★質問1.
    実は、2015/10/18に「SeleniumBasic v2.0.5.0」を、
    ダウンロードして使い始めてみました。

    その中で、サンプルコードとして添付している、

    Private Sub Use_Chrome()
    Dim driver As New ChromeDriver
    driver.Get “https://www.google.co.uk”
    driver.Quit
    End Sub

    を実行すると、問題なくChromeが稼動しますが、

    貴サイトの、

    Private Sub Use_Chrome_Test()
    driver = createoleobj(“SeleniumWrapper.WebDriver”)
    driver.start(“chrome”)
    End Sub

    では、

    コンパイルエラーとして、
    createoleobj の
    Sub mataha Funcyion が定義されていませんと表示されます。

    貴サイトのコードを実行したい場合、
    SeleniumBasic v2.0.5.0 以外にも、
    インストール部品がなにかひつようなのでしょうか?

    ★質問2.
    「SeleniumBasic v2.0.5.0」のサンプルコードには、
    Safariの記述が無いのですが、

    質問1.の問題がクリアできましたら、

    Private Sub Use_Chrome_Test()
    driver = createoleobj(“SeleniumWrapper.WebDriver”)
    driver.start(“safari”)
    End Sub

    このような記述で、Safariも開くのでしょうか?
    ※Safariは、safari 5.1.7 for Windows版です。

    ちなみに、既定の参照設定に加え、
    Selenium Type Library
    SeleniumWrapper Type Library
    Microsoft Internet Controls
    への参照設定は行なっています。

    また、当方のOSは、Windows7(64)
    EXCELは、EXCEL2013(15.0.4573.1003) MSO(15.0.4753.1003)32bit
    です。

    急なお便りのうえに、いきなりの質問をさせて頂き、
    誠に申し訳御座いません。

    Selenium初心者のため、幼稚な質問かもしれませんが、
    もし、お時間が御座いましたら、お教え頂ければ助かります。

    何卒、宜しくお願い申し上げます。

  4. 質問1への回答

    > コンパイルエラーとして、
    > createoleobj の
    > Sub mataha Funcyion が定義されていませんと表示されます。

    ここに記載しているのはUWSC用のコードであり、createoleobj もUWSCの関数です
    当然VBAでは定義されていませんので、そのエラーが出るのが正しいです

    VBAでしたら CreateObject でしょう
    あるいは、サンプルのコードをそのまま使われたら良いと思います

    質問2への回答

    Windows向けのSafariのWebDriverが提供されてないんじゃないでしょうか
    そもそもWindowsのSafariって何年も前にサポート打ち切られていたんじゃなかったでしたっけ?

    もしかしたら動くかもしれませんが、古いブラウザを使い続けるのはよくないです
    なるべく別のブラウザを使ってください

  5. stuncloud様へ、
    早速のお返事をいただき、有難う御座いました。

    すみません、まったくトンチンカンは質問で、
    大変失礼を致しました。

    いまから、UWSCの勉強も始めてみます。

    ちなみに、EXCELのVBAのほうですが、
    Seleniumサンプルコードを参考に、
    いろいろいじってましたら、

    Chrome
    Firefox
    Ie
    Safari
    Opera

    の5つのプラウザを無事、開くことが出来ました。
    そして、Googleページも表示できました。

    Firefoxだけ、Ver-41.0.2 と、verが新しすぎるせいか、
    Googleページが表示できませんでしたが、
    多分、ver34以下にすれば問題ない気がします。

    こんなにたくさんのプラウザが開けるのは、
    大助かりです。
    当方の作業が、かなりはかどります。

    stuncloud様のサイトを参考に、
    いろいろ勉強させていただきます。

    今回は、ありがとうございました。

  6. stuncloud様へ、
    以前に一度、質問させていただきました、すすむです。

    前回は、御世話になりました。

    貴サイトから、いろいろ勉強させていただき、
    感謝いたして降ります。

    本当に有難うございます。

    その後、かなり「UWSC+SeleniumVBA」でのテストツールも、
    仕上がってきたのですが、
    どうしても方法がわからない部分がありましたので、

    stuncloud様のお知恵を拝借したいと思い、
    再度、連絡させていただきました。

    もし、お時間がございまして、対処法のアドバイスが、
    いただけるようでしたら、お知恵をお借りできればと思います。

    勝手なお願いですが、宜しくお願い致します。

    【質問内容です。】

    プラウザは「Forefox ver.34」です。
    driverは、 New SeleniumWrapper.WebDriver
    を使用しています。

    サイト内で、特定の「TEXT」を含むアンカーをクリックさせたくて、

    driver.FindElementByPartialLinkText(TEXT, 1000).Click

    という行を実行しています。

    サイト内のアンカー中に、特定の「TEXT」を含むアンカーがあれば、
    もんだいないのですが。
    (最初に現れた目的のアンカーをクリックしてくれているようです。)

    指定した「TEXT」を含むアンカーがない場合には、

    実効時エラー’2146233088(80131500)
    Element not found.Method=partiallinktext, value=TEXT

    のエラー(ポップアップ)がでて、VBAがストップします。

    ・・・当然のことではあるのですが・・・。

    「TEXT」が存在しないサイトに出会うたびに、
    VBAがとまるので、

    driver.FindElementByPartialLinkText(TEXT, 1000).Click

    を実行する前に、

    サイト内のアンカーテキストに、「TEXT」が、
    含まれているものがあるかどうか、判断して、
    ない場合には、この行をスキップさせるような方法はございませんでしょうか?

    プログラム初心者のため、もしかしましたら、
    プログラム上の幼稚な質問かもしれませんが、
    もし、お時間が御座いましたら、お教え頂ければ助かります。

    何卒、宜しくお願い申し上げます。

    • FindElement*()系は見つからなかったらエラーを返すようです
      あるかどうか疑わしい場合はFindElements*()を使うべきでしょう
      必ずコレクションを返すので見つからなければCountが0になります

      set elements = driver.FindElementsByPartialLinkText(TEXT, 1000)
      if elements.Count = 0 then
       Messagebox “見つかりませんでした”
      else
       elements.Item(0).Click
      end if

      おそらくこんな感じです

  7. stuncloud様へ、
    有難う御座いました。

    参考にさせて頂き、問題は無事解消できました。
    いつも、目からウロコの情報をいただき有難うございます。

    また、プログラムが一歩前進できました。
    初心者の私には、すごく有難いです。

    あと、重ねて申し訳ないのですが、
    SekeniumVBA で、Forefox や Chrome などを、
    プラウザの最下部まで、スクロールさせることは出来ないのでしょうか?

    sendkey など、いろいろやっているのですが、
    どうしても、スクロールさせることが出来ません。

    いろいろやるなかで、

    driver.SendKeys Chr(13) + Chr(10)

    だけは、Forefox や Chrome などのプラウザが、
    多少反応したので、

    どうにかして、Page down かなにかのキーを、
    送信できればと思うのですが・・・。

    これが出来れば、やっとこさ、
    目的のプログラムが完成します。

    おいそがしい中とは存じますが、
    もし、方法をご存知で、お時間が御座いましたら、
    ご教授頂ければ有難いです。

    本当に厚かましいお願いで申し訳ございません。
    お手すきの折にでも、何卒、宜しくお願い致します。

  8. stuncloud様へ、
    早速のお返事をいただき、有難う御座いました。

    早速いろいろやってみているのdすが、

    プラウザがIEであれば、

    ExcelVBAにて、

    Dim pageHeight As Integer

    pageHeight = objIE.Document.body.scrollHeight
    objIE.Navigate “JavaScript:scrollTo(0,” & pageHeight & “)”

    で、スクロールできたのですが・・・。

    SeleniumVBAだと、

    Dim pageHeight As Integer

    pageHeight = driver.Document.body.scrollHeight
    driver.Navigate “JavaScript:scrollTo(0,” & pageHeight & “)”

    ・・・が出来ません。

    原因は、
    1.
    Seleniumのdriverオブジェクトに、
    Document.body.scrollHeight の値が無いこと

    2.
    そもそも、Seleniumのdriverオブジェクトに、
    Navigate “JavaScript:scrollTo(0,” & pageHeight & “)”
    が使えない・・・?

    のようなことだと思うのですが、

    もし、SeleniumVBAで、プラウザのスクロールに使えそうな、
    Javascriptの情報サイトがございましたら、
    お教え頂ければ有難いです。

    あつかましいお願いだと思いますので、
    無視していただいてもOKです。

    いろいろ調べまわってみます・・・。
    ヒントを与えていただき、有難う御座いました。

    • Javascriptの実行方法はこの記事のおまけとして記載しています
      それを意図して回答したのですが、見落とされていましたか?

      また、WebDriverオブジェクトにはDocumentプロパティはないです、Navigate()もないです
      SeleniumBasic付属のヘルプファイルを熟読してください
      各クラスがどんなメンバを持つかはそれでわかります
      安易に質問をされる前に、そういった最低限のことをしておいてください

      • stuncloud様へ、
        有難うございました。

        また、大変失礼を致しました。
        最低限の事を始めてみます。

        本当にいろいろと、
        有難う御座いました。

      • stuncloud様へ、
        いろいろと有難う御座いました。

        詳しくないため、
        「Javascriptの実行方法はこの記事のおまけとして記載・・・」
        自体が、チンプンカンプンで意味不明だったのですが。

        その内容に沿って、いろいろ調べて触りまくっていたら、
        ついにSeleniumで、スクロールが出来ました。

        今回は、たびたびの質問、
        ご丁寧に回答頂き本当に有難う御座いました。

        やりたい事のソフトも完成しました。

        感謝致します。
        本当に有難うございました。

        ますますの貴サイトの繁栄をお祈りいたします。

  9. 初めまして、
    UWSC で Firefox を動かしたくて、検索サイトから辿り着きました。
    宜しくお願い致します。

    SeleniumBasic をインストール後に Selenium IDE にアドオンを入れてあります。
    Firefox の中の「ツール」メニュー内には、「Selenium IDE」があり、Selenium IDEそのものは正常に起動する状態です。

    貴サイトの、chrome を firefox に変更して

    driver = createoleobj(“SeleniumWrapper.WebDriver”)
    driver.start(“firefox”)

    上記の2行だけを UWSC で実行しますと、下記のようなエラーになってしまいます。

    COM_Error:クラス文字列が無効です,ProgID: “SeleniumWrapper.WebDriver”
    1行目:DRIVER = CREATEOLEOBJ(“SeleniumWrapper.WebDriver”)

    お時間がございましたら、対処方法を教えて頂きたく宜しくお願い致します。

  10. stuncloud 様

    お返事を有り難うございました。
    stuncloud様のUWSC関係の部分はみんな読んだつもりでしたが、抜けがあったようです。
    どうも有り難うございました。

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中