VBAでスクレイピングするための基本

# VBAでスクレイピング
Excel VBAでスクレイピングするための基本を纏めたい、そんなモチベーションから記事です。

# 基本の流れ
VBAの構文としては下記の6つのステップを覚えておけば何とかなる気がしています。
あとは、プログラミングの前や作業の中で、実際に目的のWebサイトにアクセスしてブラウザの開発モードを駆使して、目的の情報がどのようなタグやどのような属性名の中にあるか分析することが大事だと思います。
（Javascriptの絡みでボタンを押せないパターンがあるので（.clickメソッド、.Submitメソッドが効かない）、その方法について別記事を後ほど作成しようと思います。）

## 6つのステップ
1. IEオブジェクト作成
    - `Dim objIE As InternetExplorer`
    - `Set objIE = CreateObject("InternetExplorer.Application")`
2. IEオブジェクト.NavigateメソッドでURLにアクセス
    - `objIE.Navigate "http://hogehoge.co.jp"`
3. IEを待ってあげる（ページ取得の時間）
    - `Do While objIE.Busy = True Or objIE.ReadyState <> 4`
    - 　　`DoEvents`
    - `Loop`
3. DOMを取得する。
    - 例えば下記はHTMLのClass名で取得する例。他にもtag名やID名で取得できる。配列として帰ってくるので単体を取得する場合は添え字(1)などを付けて取得するか、For Eachで要素すべてにアクセスする。
        - `Dim ojbDOM as Object`（またはas HTMLDocument）
        - `objDOM = objIE.Document.getElementsByClassName("クラス名")(1)`

4. DOMを検索して目的の情報を取得する。
    - 例えば`<li class="クラス名">うんこ</li>`の「うんこ」という文字列を取得する場合は、`objDOM.innerText`で取得できる。他にも下記を使って目的の情報にアクセスする。
        - タグを含めたDOMを取得する。
            - `objDOM.innerHtml`、`objDOM.outerHtml`
        - タグとタグに挟まれたテキストを取得する。
            - `objDOM.innerText`, `objDOM.outerText`
5. （オプション）認証等の為にhtmlのテキストボックスに値(うんこ)をセットしてSubmitボタンを押す場合
    - `Dim objtag As Object`
    - `objtag In objIE.Document.getElementsByTagName("input")(0)`
    - `objtag.Value = "うんこ"`
    - `objtag In objIE.Document.getElementsByTagName("input")(1)`
    - `objtag.click`



## 事前準備
VBE参照設定　→　「MicroSoft Internet Controls」
これでIEのクラスが利用できる。


# コードサンプル

基本のプロシージャ、そこから呼ばれるIEを操作するプロシージャ、あとIEをウェイトする関数を2つ、以上に分けてサンプルを書きました。
下記のコードの流れをざっくり謂うと

1. ”http://hogehoge.co.jp”にアクセス

2. 「うんこ」というキーワードを検索
3. 検索結果ページの"Product__titleLink"というクラス名を持ったhtmlタグをすべて取得しアクティブシートの1列目に取得したinnerHTMLを列記していく。

以上の流れです。実際には、innerHTMLで取得できる内容はタグと属性と要素との集まりなので、実際に業務で必要になる情報の多くは、mid関数やinstr関数等を使って加工する必要があるかと思います。今回は、サンプルということでそこまではやりません。


```VB  
Const MYURL = "http://hogehoge.co.jp"
Const SEARCH_WORD = "うんこ"

Sub スクレイピング()
    Dim objIE As InternetExplorer
    Dim url As String
    Dim ws As Worksheet

    Set ws = ActiveWorksheet
    'IE起動
    Set objIE = CreateObject("InternetExplorer.Application")
    Call access(objIE,MYURL,ws)
    objIE.Visible = True   
    objIE.Quit
    Set objIE = Nothing
End Sub
```

```vb
`URLにアクセスする。
Sub access(ByRef objIE As Object, ByVal url As String, ByVal ws As WorkSheet)

    Dim objtag, objsubmit As Object
    Dim MyRow As Long

    objIE.Navigate url
    Call IEWait(objIE)    'IEを待機
    Call WaitFor(3)    '3秒停止

    'yschspというテキストボックスを検索して、検索ワードをセットする。
    For Each objtag In objIE.Document.getElementsByTagName("input")
         If InStr(objtag.outerHTML, """HOGEHOGE""") > 0 Then
             objtag.Value = SEARCH_WORD
             Exit For
         End If
    Next    
    '検索ボタンを押す
     For Each objsubmit In objIE.Document.getElementsByTagName("input")
         If InStr(objsubmit.outerHTML, """検 索""") > 0 Then
             objsubmit.Click
             Call WaitFor(3)
             Exit For
         End If
    Next

    For Each objtag In objIE.Document.getElementsByClassName("Product__titleLink")
        MyRow = ws.Cells(Rows.Count,1).End(xlUp).Row + 1
        ws.Cells(MyRow, 1).Value = objtag.innerHTML                 
    Next
End Sub
```

```vb
'IEを待機する関数
Function IEWait(ByRef objIE As Object)
    Do While objIE.Busy = True Or objIE.ReadyState <> 4
        DoEvents
    Loop
End Function
```

```vb
'指定した秒だけ停止する関数
Function WaitFor(ByVal second As Integer)
    Dim futureTime As Date
    futureTime = DateAdd("s", second, Now)
    While Now < futureTime
        DoEvents
    Wend
End Function
```

# 終わり
以上です。
冒頭でも書きましたが、clickメソッドが使えなかったケースへの対応や、DOMを加工してほしい情報を切り取る手法などについては、後ほど別記事を作成予定です。もし宜しければ そちらもご覧ください。