この記事では
- WinHTTPの実践的な使い方の例としてリンクの一覧を取得するサンプルを作ります。
- HTMLの(最低限の)知識が必要です。
- シリーズものになります。その1はこちら→VBAでウェブスクレイピング_WinHTTP編その1 - 適材適所
WinHTTPでスクレイピングしてリンクのURL一覧を作ってみる
その3ではWinHTTPを使うためのHTTPの説明をしました。 今回からWinHTTPの実践的な使い方に入っていきたいと思います。
スクレイピングの目的は色々ありますが、いくつかこんなことができるよ的なサンプルを作っていきたいと思います。
その第一段として「WinHTTPを使って対象のページ上のリンク一覧をワークシートに書き出す」というものを作ってみようと思います(そんな需要はあるかわかりませんが・・・)。
次のコードを実行すると、「url」変数に指定されたウェブページにあるリンクの文字列とリンク先URLをアクティブなシートに出力します。
コード
実行前に参照設定を行います。
Microsoft WinHTTP Services, version○
Microsoft HTML Object Library
Sub WinHTTP_Sample() Dim req As WinHttp.WinHttpRequest: Set req = New WinHttp.WinHttpRequest Dim url As String:url = "https://www.yahoo.co.jp/" req.Open "GET", url req.Send If req.Status <> 200 Then MsgBox "レスポンスエラー" Exit Sub End If Dim html As Object: Set html = New HTMLDocument html.Write req.ResponseText Dim wrtRow As Long: wrtRow = 1 Dim a As HTMLAnchorElement For Each a In html.getElementsByTagName("a") Cells(wrtRow, 1).Value = a.innerText Cells(wrtRow, 2).Value = a.href wrtRow = wrtRow + 1 Next a End Sub
コードの解説
2行目の
Dim req As WinHttp.WinHttpRequest: Set req = New WinHttp.WinHttpRequest
は「req」という変数名でオブジェクトを準備しています。参照設定を行っているので、データ型をそのまま指定できます。
4行目
req.Open "GET", url
urlへのHTTP接続のための準備をするようなイメージでしょうか。
引数は3つあります。
1つ目は、HTTPの動詞です。GET や POSTがメインとなることでしょうか。
2つ目は、URLを指定します。
3つ目は、開き方の指定です。「同期」or「非同期」のどちらかです。
同期モードは、次の「Send」メソッド実行時にサーバからの応答を全部受信したら制御が戻ってきます。つまり通信の状態をこちら側で管理する必要がなくなります。
Falseが同期、Trueが非同期です。省略値はFalseの同期です。基本は省略値でいいと思います。
5行目
req.Send
サーバに向けてリクエストを送信します。
引数はBodyです。POSTメソッドでパスワード等を送信する際に指定することができます。
Openのところで同期モードで設定したので、通信の制御は不要です。
7~10行目
If req.Status <> 200 Then MsgBox "レスポンスエラー" Exit Sub End If
レスポンスコードを調べます。
レスポンスコードは正常の場合200です。
200以外の場合は処理を終了します。
12~13行目
Dim html As Object: Set html = New HTMLDocument html.Write req.ResponseText
HttpRequest#ResponseTextプロパティに、生のHTMLが入っています。 今回は、これをHTMLDocumentにパースしてもらい、扱いやすくします。 生のHTMLを正規表現で抽出した方が処理は速いので、どちらを選択するかは要求されるもの次第になります。
HTMLDocumentの書き方はなぜこうなるのかはわからず・・・。
16~21行目
For Each a In html.getElementsByTagName("a") Cells(wrtRow, 1).Value = a.innerText Cells(wrtRow, 2).Value = a.href wrtRow = wrtRow + 1 Next a
aタグのテキストとaタグのhref(リンク先)をシートに出力してます。 getElementsByTagNameの使い方は下記記事で言及しています。
おわりに
WinHTTPでリンクの一覧を取得するサンプルを作ってみました。 こんな感じでWinHTTPを使うことで、ブラウザに依存せずにスクレイピングをすることができます。
要求をオープンして送る。返ってきたものを処理する。これがWinHTTPでスクレイピングする際の基本形になります。 この基本さえ押さえてしまえば、あとはウェブページの動きを分析して処理を組み立てることができます。
次回もWinHTTPを使ったサンプルを作ってみたいと思います。
ここまでお読みいただき、ありがとうございました。
参考サイト
IWinHttpRequest::Open method - Win32 apps | Microsoft Docs VBAでのHTMLDocument VBAでHTMLの解析をしたいと思っています。 … - 人力検索はてな