【チュートリアル】VBAでIE自動化ツールを作る(その4) 要素の取得パターン

こんにちは、自動化エンジニアをしています。kozuです。

エクセルVBAによりWebページの要素(テキストボックス、ボタンなど)を操作したり、表示されている情報を取得する自動化ツールの開発方法を紹介します。実際のWebサイトを自動操作し情報を取得するマクロの開発を通して、自動化ツールの開発について学ぶことができます。

本連載では、チュートリアルということでVBAの開発手順から始め、IEの操作についてどのようなページでも共通で使用できるコード(共通部品)を作成します。最初に共通部品を作成しておくことで、自分でIEの自動化ツールを作成する際に少量の実装で効率よく開発できるようになります。

この章では、要素(ボタンやテキストボックス)を取得するための特定方法についていくつかのパターンを紹介します。

1.対象者

ブラウザで定期的に手作業で行っているデータ入力やデータ収集等の作業から開放されたい、楽したいと考えている方を対象に、エクセルVBAで自動化するツールの開発ができるようになることを目指しています。プログラミングの経験がない方でも、コードをコピーすれば開発できるようになっています。

2.開発環境

以下の環境を使用します。
バージョンは異なっていても問題ないと思います。
・OS:Windows10
・エクセル:Microsoft Excel2007
・ブラウザ:InternetExploer11

3.要素の取得①(idで特定)

基本的に1つのHTMLでidが重複することはないため、idで指定すれば途中の構造によらず特定することができます。HTMLの要素にidが設定されている場合はこの方法を採用するとよいです。

「document.getElementById(id名)」でidを指定して要素を取得します。以下のコードを「Console」で実行すると確認できます。

document.getElementById('hplogo')

パターン_ID2

VBAで実装すると以下のようになります。

objIE.document.getElementById("hplogo")

4.要素の取得②(classで特定)

ページ内に同じ要素が複数ある場合、共通のデザイン設定をするために同じclassを要素に設定しています。そのため、1つの要素ではなく同じデザインの複数の要素をまとめて取得する場合に有効です。例えば、Googleの検索結果のタイトルを取得するときに使用できます。要素の配列を取得するため、最後の[N(0スタートの整数)]で何個目かを指定しています。プロシージャの名前の通り、複数形になっているので複数の要素が取得されます。

document.getElementsByClassName('LC20lb DKV0Md')[0]

パターン_class2

VBAで実装すると以下のようになります。

objIE.document.getElementsByClassName("LC20lb DKV0Md").Item(0)

5.要素の取得③(nameで特定)

こちらもclass同様にページ内に同じnameを設定している要素が複数ある場合があります。ページの処理(javascript)で要素を特定するために利用されます。

document.getElementsByName('q')[0]

パターン_name2

VBAで実装すると以下のようになります。

objIE.document.getElementsByName("q").Item(0)

6.要素の取得④(取得したセレクタで特定)

これは前回紹介した方法になります。Chromeの開発者ツールでセレクタをコピーしたものをそのまま使用します。そのまま使用するため簡単ですが、仕様変更でページの構造が変化した場合に特定できなくなる可能性が高くなります。セレクタのパスを複数の要素を連続で指定しているため、途中の要素が1つでも変更されたら特定できなくなります。

document.querySelector('#tsf > div:nth-child(2) > div.A8SBwf > div.RNNXgb > div > div.a4bIc > input')

パターン_セレクタ2

VBAで実装すると以下のようになります。

objIE.document.querySelector("#tsf > div:nth-child(2) > div.A8SBwf > div.RNNXgb > div > div.a4bIc > input")

7.要素の取得パターン⑤(属性で特定)

上記で説明したidやclass、nameで特定できない場合、その他の属性で指定する方法があります。プロシージャはget~ではなく、「querySelector」または「querySelectorAll」を使用します。前者は要素を1つ、後者は要素を複数取得します。

document.querySelector('[title="検索"]')

パターン_プロパティ2

VBAで実装すると以下のようになります。「"(ダブルクオーテーション)」を文字列として使用する場合は2重にします。

objIE.document.querySelector("[title=""検索""]")

以下のようにタグ名と合わせて指定したり、nameやclassを属性として指定することも可能です。「querySelector」を使用すれば柔軟な指定ができます。

Set objEle = objIE.document.querySelector("input[title=""検索""]")
Set objEle = objIE.document.querySelector("input[name=""q""]")
Set objEle = objIE.document.querySelector("input[class=""gLFyf gsfi""]")

8.要素取得プロシージャ実装

最後に、上記で紹介した要素取得のプロシージャを実装します。「IEControl」に以下を追加してください。

' ************************************************
'  関数名:GetHtmlObjById
'  概要:要素取得(getElementById)
'  引数:objIE(IEオブジェクト)
'           id (要素のid)
'  戻り値:HTML要素
' ************************************************
Public Function GetHtmlObjById(ByVal objIE As InternetExplorer, ByVal id As String) As Object
   'IEが完全に表示されるまで待機
   Call WaitIE(objIE)
   
   Set GetHtmlObjById = objIE.document.GetElementById(id)
End Function

' ************************************************
'  関数名:GetHtmlObjByClass
'  概要:要素取得(getElementsByClassName)
'  引数:objIE(IEオブジェクト)
'           class (要素のclass)
'  戻り値:HTML要素
' ************************************************
Public Function GetHtmlObjByClass(ByVal objIE As InternetExplorer, ByVal class As String) As Object
   'IEが完全に表示されるまで待機
   Call WaitIE(objIE)
   
   Set GetHtmlObjByClass = objIE.document.getElementsByClassName(class)
End Function

' ************************************************
'  関数名:GetHtmlObjByName
'  概要:要素取得(getElementsByName)
'  引数:objIE(IEオブジェクト)
'           name (要素のname)
'  戻り値:HTML要素
' ************************************************
Public Function GetHtmlObjByName(ByVal objIE As InternetExplorer, ByVal name As String) As Object
   'IEが完全に表示されるまで待機
   Call WaitIE(objIE)
   
   Set GetHtmlObjByName = objIE.document.getElementsByName(name)
End Function

' ************************************************
'  関数名:GetElementByQuerySelector
'  概要:要素取得(querySelector)
'  引数:objIE(IEオブジェクト)
'           selector (要素のセレクタ)
'  戻り値:HTML要素
' ************************************************
Public Function GetHtmlObjByQuerySelector(ByVal objIE As InternetExplorer, ByVal selector As String) As Object
   'IEが完全に表示されるまで待機
   Call WaitIE(objIE)
   
   Set GetHtmlObjByQuerySelector = objIE.document.querySelector(selector)
End Function

' ************************************************
'  関数名:GetElementByQuerySelectorAll
'  概要:要素取得(querySelectorAll)
'  引数:objIE(IEオブジェクト)
'           selector (要素のセレクタ)
'  戻り値:HTML要素
' ************************************************
Public Function GetHtmlObjByQuerySelectorAll(ByVal objIE As InternetExplorer, ByVal selector As String) As Object
   'IEが完全に表示されるまで待機
   Call WaitIE(objIE)
   
   Set GetHtmlObjByQuerySelectorAll = objIE.document.querySelectorAll(selector)
End Function


ここまでで、HTMLのページを自動操作するために要素を特定する方法について紹介しました。次回は取得した要素の操作を実装します。

この記事が気に入ったらサポートをしてみませんか?