エクセルVBAでIEを操作するクラスにリンクテキストでa要素を探してリンクする方法

anchor

photo credit: jack cousin Whitby: Anchor and beach via photopin (license)

みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。

エクセルVBAでIEスクレイピングをするときに便利なクラスの作り方をお伝えしております。

前回の記事はこちら。

エクセルVBAでIEを操作するクラスにname属性で取得した要素から内容を取り出すプロパティを作成
エクセルVBAでIEスクレイピングをするときに便利なクラスの作り方をお伝えしております。今回は、エクセルVBAでIEを操作するクラスにname属性で取得した要素から内容を取り出すプロパティを追加していきます。

name属性で要素を探してその内容を取り出すプロパティの作り方をお伝えしました。

今回は、リンクテキストでa要素を探してそのURLのページを開く方法です。

便利そうじゃないですか?

ということで、エクセルVBAでIEを操作するクラスにリンクテキストでa要素を探してリンクする方法です。

では、行ってみましょう!

スポンサーリンク

前回のおさらい

まず、前回のおさらいからです。

まずIEを操作するクラスIEObjectです。

Public IE As InternetExplorer
Public Document As HTMLDocument

Private Sub Class_Initialize()
    Set IE = New InternetExplorer
    IE.Visible = True
End Sub

Private Sub Class_Terminate()
    IE.Quit
End Sub

Public Sub Navigate(ByVal url As String)
    IE.Navigate url
    Wait
    Set Document = IE.Document
End Sub

Public Sub Wait()
    Do While IE.Busy = True Or IE.readyState < READYSTATE_COMPLETE
        DoEvents
    Loop   
End Sub

Public Property Get ContentByName(ByVal nameAttr As String) As String
    ContentByName = Document.getElementsByName(nameAttr)(0).Content
End Property

だいぶ多機能になってきました。前回はContentByNameプロパティを作りました。

それを検証するための標準モジュールのプロシージャがこちらです。

Sub MySub()
    
    Dim ieObj As IEObject: Set ieObj = New IEObject
    ieObj.Navigate "https://tonari-it.com"
    
    Debug.Print ieObj.ContentByName("description")
    Debug.Print ieObj.ContentByName("keywords")
        
End Sub

特定のリンクテキストを持つa要素を取得するメソッド

今回は、ページ内で特定のリンクテキストを持つa要素を探すして、それにリンクするという処理を実現していきたいと思います。

例として、以下のリンクを目指します。

ターゲットとするリンクテキスト

「詳細・お申込みはこちら」というやつですね。みんなに踏んで欲しいやつです。

それで、IEObjectクラスに以下のようなFunctionプロシージャを追加しました。

Public Function GetElementByLinkText(ByVal text As String) As HTMLAnchorElement
    
    Set GetElementByLinkText = Nothing
    
    Dim anchor As HTMLAnchorElement
    For Each anchor In Document.Links
        If anchor.innerText = text Then
            Set GetElementByLinkText = anchor
            Exit Function
        End If
    Next anchor
    
End Function

Functionプロシージャなのでメソッドになりますね。GetElementByLinkTextメソッドです。

目的はリンクなので、そこまでの処理を含めても良いのですが、汎用性を考えてa要素を返すメソッドにしました。

リンクは標準モジュールから既に実装済みのNavigateメソッドを呼び出します。

Linksプロパティで取得したa要素コレクションをループ

まず6行目ですが、HTMLDocumentオブジェクトのLinksプロパティで、a要素をコレクションで取得しています。

HTMLDocumentオブジェクト.Links

getElementsByTagNameメソッドでa要素を指定しても良いのですが、こっちのほうが短い。

あとは、取得したa要素のコレクションについてループをして、パラメータで与えた文字列にヒットすれば、それを戻り値としてセットしてあげればOKですね。

「含む」にしたい場合は、条件式をInStr関数使うなり、Like演算子使うなりしてあげればOKです。

なぜプロパティではなくメソッドなのか

なぜプロパティにせずにメソッドにしたかというと…けっこう微妙なのですが、このプロシージャの戻り値が「Nothing」であることも多そうなので、メソッドにしました。

なんか、プロパティにしてNothingが多いのって、個人的には違和感が…。あと、既存のgetElement~シリーズもメソッドですし。このへんは結構好みもあると思いますが。

特定のリンクテキストを持つa要素を取得しリンクする

では、標準モジュールでテスト用のプロシージャを作って確認してみましょう。

Sub MySub()
    
    Dim ieObj As IEObject: Set ieObj = New IEObject
    ieObj.Navigate "https://tonari-it.com"
    
    Dim text As String: text = "詳細・お申込はこちら"
    
    Dim anchor As HTMLAnchorElement
    Set anchor = ieObj.GetElementByLinkText(text)
    
    If Not anchor Is Nothing Then
        ieObj.Navigate anchor.href
    Else
        Debug.Print text; "をテキストとするa要素はありませんでした"
    End If
    
    Stop
    
End Sub

9行目で先ほどのメソッドを呼び出しています。

それで、11行目からIf文の分岐がありますが、目的のリンクテキストのa要素が見つからなかった場合の処理ですね。

存在しているときだけNavigateメソッドでページを開くようにしています。

実行すると、以下のようにページが開きますね。

リンク先ページ

ちなみに、今回作ったメソッドは、最初に一致するリンクテキストを見つけたら、そのa要素を返します。

目的のリンクテキストがページ内に複数ある場合には想定しない動きをする可能性がありますので、注意くださいね。

まとめ

以上、エクセルVBAでIEを操作するクラスにリンクテキストでa要素を探してリンクする方法をお伝えしました。

このメソッド、実はPythonのseleniumモジュールで標準であったので、「いいな~」と思っていたものでした。

VBAの場合、ひと手間いりますが、自作しておけば使い回しできますので、ぜひ…!

次回はテーブルにトライしたいです。

エクセルVBAでIEを操作するクラスにテーブルのデータを取得するメソッドを追加する方法
エクセルVBAでIEスクレイピングをするときに便利なクラスの作り方をお伝えしております。今回は、エクセルVBAでIEを操作するクラスにテーブルのデータを取得してデバッグ出力するメソッドを追加していきます。

どうぞお楽しみに!

連載目次:エクセルVBAでIEを操作するクラスを作る

エクセルVBAでInternetExplorerを操作してWebスクレイピング、まだまだ現役で必要となる現場もあるでしょう。このシリーズでは、IEを使ったスクレイピングをするときに便利なクラスの作り方をお伝えします。
  1. エクセルVBAでIEを操作するもっとも簡単なクラスを作成する方法
  2. エクセルVBAでIEを操作するクラスでWebページを開くメソッドを追加する
  3. エクセルVBAでIEを操作するクラスに読み込み待ちとドキュメント取得の機能を追加する方法
  4. エクセルVBAでIEを操作するクラスにname属性で取得した要素から内容を取り出すプロパティを作成
  5. エクセルVBAでIEを操作するクラスにリンクテキストでa要素を探してリンクする方法
  6. エクセルVBAでIEを操作するクラスにテーブルのデータを取得するメソッドを追加する方法
  7. エクセルVBAでIEを操作するクラスにWebページのテーブルデータをシートに書き出すメソッドを追加する
  8. エクセルVBAでIEを操作するクラスに検索入力&ボタンクリックのメソッドを追加する方法
  9. エクセルVBAでIEを操作するクラスにログイン処理をするメソッドを追加する方法
  10. エクセルVBAによるIEを操作するクラスに指定秒数の待ち時間を入れるメソッドを追加する
タイトルとURLをコピーしました