前回の記事ではSeleniumVBAを使ったChromeでのWebスクレイピングについて説明しました。
前回の記事はこちら
今回はSeleniumVBAでスクレイピングを行っていくうえで必要なメソッドについて、備忘録的に上げていくことにします。
このサイトを使ってSleniumVBAに少しでも慣れていただければ幸いです。
なお、2022年9月以降インストール方法の変更により変数の宣言方法が変わっています。
詳しい記事はこちらをご確認ください。
VBAを使ったものではありませんが、Seleniumを勉強する為の基本的な書籍です。ブラウザやキー操作の基本的なコマンドは共通していますのでコードを書く際の参考になります。
ウィンドウの操作
フレームの移動
表示しているサイトがフレーム構造(サイト内が枠で分割されている)になっている際は移動の際に適したフレームにフォーカスさせる必要があります。
フレーム間を移動するメソッドは以下の通りです。
- driver.SwitchToFrame “フレーム名”
- driver.SwitchToDefaultContent
これを行うことでフレーム内の要素を取得することができます。
また別のフレームに移動する際は一度親フレームに戻る必要があるので、SwitchToDefaultContentメソッドで元のフレームに戻るようにします。
ページ上のアラートの操作
操作している際にページ上にアラートが表示されることがあります。
これはJavaScriptによって作成される画面です。
アラートの要素はそのままでは取得できませんが、アラートを操作するメソッドがあります。
- driver.AcceptAlert
- driver.GetAlertText
以下は画面上のテキストを取得し、受け入れるコードです。
driver.GetAlertText
driver.AcceptAlert
新しいタブを開く
新しいタブを開くにはJavaScriptを使って以下のように記述します。
- driver.ExecuteScript “window.open(‘URL’)”
なおExecuteScriptの()内の文字列はVBAのコードなので”で囲いますが、JavaScriptの()内の文字列は’(シングルコーテーション)になります。
VBAとJavaScriptで異なりますのでご注意ください。
SeleniumBasicですがJavaScriptを使ったコードについては以下で詳しく記載しています。
要素の取得
条件に合うすべての要素の取得(FindElementsメソッド)
条件にマッチしたすべての要素を取得したい場合に使用します。
メソッドについては以下2通りの書き方があります。
- FindElementsByTagName(“●●●”)
- FindElementsByName(“●●●”)
- FindElements(by.tagName,”●●●”)
- FindElements(by.Name,“●●●”)
以下ではTagがTableであるすべての要素を取得し、数を数えています。
driver.FindElementsByTagName("table").Count
FindElementsメソッドは条件に合う情報をまとめて取得してその中の要素を検索するときによく使います。
Excel VBAでいうWorksheetsコレクションとRangeオブジェクトのような関係です。
一意な情報を取得するFindElementメソッドより高度な取得方法になります。
Countメソッド
要素の数を取得する際にはCountメソッドを使用します。
メソッドは以下の通り。
- driver.FindElementsBy〇〇〇(“●●●”).Count
このコードはFindElements内の要素数を確認するときによく使います。
特定の要素へのマウスオーバー
マウスを上部に置くと表示されるようなドロップダウンメニューバーなどに使用します。
以下は私のWordPress内の投稿ボタンです。投稿の上にマウスを置くとリストが表示されます。
要素の中央にマウスを動かす場合はMoveToElementメソッドを使用します。
このメソッドはユーザー操作を実現するActions classの中に存在します。
- driver.ActionChain.MoveToElement(WebElement)
WebElement内にはマウスオーバーする要素を記載します(driver.FindElement〇〇〇の書き方です)。
以下は要素の中央にマウスを動かすコードです。
ActionChainに格納した内容を実行する際はPerformメソッドを使います。
Dim element As WebElement
Set element = driver.FindElementBy〇〇〇("●●●")
driver.Actions.MoveToElement(element).Perform
なお私が使っている感じではあまり安定しないように思います。
その場合は直接隠れた要素を取得する方が好ましいかと思います。
要素の内容の取得
GetTextメソッド
各要素のインナーテキストを抜き出す際はGetTextメソッドを使います。
メソッドは以下の通り。
- driver..FindElementBy〇〇〇(“”).GetText
このコードはWeb上のインナーテキスト=表示されている情報を正確に取得できているかを見るうえで重宝します。
MsgBox 上記のコード
とすることで取得したTextを確認することもできます。
なおGetTextメソッドで取得できないテキストも存在します。
SeleniumBasicですがテキストの取得については以下で詳しく記載しています。
要素内の属性値の取得
GetAttributeメソッド
各要素内の属性値を取得する際はGetAttributeメソッドを使います。
メソッドは以下の通り。
- driver.FindElementBy〇〇〇(“”).GetAttribute(“属性”)
HTMLの要素には、属性というものが付いています。
具体的には以下のように表記されます。
<要素名 属性="属性値">
この属性値にあたる部分を取得する際にGetAttributeメソッドを使用します。
Attributeメソッドの引数には属性を指定します。
なおJavaScriptによって各要素に付加されている属性、属性値も存在します。
これはデベロッパーツールのプロパティで見ることができます。
これらはJavaScriptでの処理によって生成されたものの為、HTML上には表示されません。
ただこれらも同様にGetAttributeメソッドで取得できます。
最近は動的に生成された情報も多いので、JavaScriptの理解も必要になります。
SeleiumBasiceですがJavaScriptについて説明した記事は以下に記載しています。
Webページの要素の存在判定
表示しているサイト内に特定の要素が存在するかを判定するにはIsPresentメソッドを使います。
メソッドは以下の通り。
- driver.IsPresent(by.CssSelector,”●●●”))
- driver.IsPresent(by.XPath,”●●●”))
- driver.IsPresent(by.ID,”●●●”))
●●●・・・各属性の情報
検索した結果をTrue or Falseで返します。
メンバーとしては上にあるようにClass, Xpath, CssSelector, idなどがあり好きなものを指定することができます。
要素の読み込み完了まで待つ
要素の読み込みが完了するまで待つにはIsPresentメソッドを使って以下のように記載します。
Dim i As Long
'5秒待つプログラム
i = 0
Do Until i > 5
If driver.IsPresent(by.CssSelector,"Path") Then
Exit Do
End If
driver.Wait 1000
i = i + 1
Loop
一つ上で説明したIsPresentメソッドで特定の要素が存在するかを判定し、存在する(True)までDo~Loopで処理します。
Seleniumにはもともと読み込み完了まで待つ機能がありますがページ内遷移など読み込み完了まで待たないケースがあります。
この不安定さをなくすために特定の要素が出てくるまで待つコードとして使用します。
また以下ではサブルーチン化しています(driverはグローバル変数化しておいてください)。
*Css Selectorの場合
Sub CssConfirmation(ByVal Path As String)
Dim i As Long
i = 0
Do Until i > 10
If driver.IsPresent(by.CssSelector, Path) Then
Exit Do
End If
driver.Wait 1000
i = i + 1
Loop
End Sub
*XPathの場合
Sub XPathConfirmation(ByVal Path As String)
Dim i As Long
i = 0
Do Until i > 10
If driver.IsPresent(by.XPath, Path) Then
Exit Do
End If
driver.Wait 1000
i = i + 1
Loop
End Sub
*IDの場合
Sub IDConfirmation(ByVal Path As String)
Dim i As Long
i = 0
Do Until i > 10
If driver.IsPresent(by.ID, Path) Then
Exit Do
End If
driver.Wait 1000
i = i + 1
Loop
End Sub
その後要素確認が必要な個所の前で以下のようにCallステートメントで呼び出してやればよいです。
Call CssConfirmation("Cssパス")
driver.FindElementByCssSelector("Cssパス")
Call XPathConfirmation("XPathパス")
driver.FindElementByXPath("XPathパス")
Call IDConfirmation("ID名")
driver.FindElementByID("ID名")
SeleniumBasicですが別で待機処理に関する記事も書いています。興味のある方はこちらもどうぞ
■ここでのまとめ
VBAをつかったWebスクレイピングはなかなか情報が少ないです。新しく学んだコードは上げていきますので少しでも役に立てれば幸いです。
VBAを使ったものではありませんが、Seleniumを勉強する為の基本的な書籍です。ブラウザやキー操作の基本的なコマンドは共通していますのでコードを書く際の参考になります。
SeleniumVBAに関する記事はこちら
【SeleniumVBA】初心者向けに導入方法についてわかりやすく説明します(Excel VBA)
【SeleniumVBA】スクレイピングで使うメソッドについて説明します。
【SeleniumVBA】Yahooメールへのログイン方法をわかりやすく説明する(Excel VBA)
【SeleniumVBA】スクレイピングで使うメソッドについて説明します2(Excel VBA)
【SeleniumVBA】スクレイピングをする為のメソッド一覧表
【SeleniumVBA】ブラウザを操作するメソッドについてサンプルコードを紹介します
【SeleniumVBA】2022年9月の更新に伴うコードの変更点について説明します。
【SeleniumVBA】アラート処理に関するメソッドについてコードを紹介します
【SeleniumVBA】待機処理に関するメソッドについてコードを紹介します
コメント