AccessのVBAでYahoo!路線情報からHTMLを取得して運賃を取得してみる
今回はAccessのフォームでYahoo!路線情報から運賃を取得するところまでを実践してみましょう。
このケースではインターネットエクスプローラーオブジェクトを利用してHTMLを取得する方法を説明します。
尚、今回はVBAの知識だけでは無く、HTMLに関する最低限の知識も必要になります。その為、少し長い記事になりますがご了承ください。
動作イメージ
出発と到着を指定して検索ボタンをクリックするとYahoo!路線情報を検索します。その後、結果ページのHTMLを取得して区間と運賃をフォームに表示します。
動作イメージは以下の通りです。
※今回はWebページを表示せず結果のみ取得します。
※今回取得する結果は最初の3経路までとします。
フォームデザイン
フォームのデザイン及び各コントロール名は以下の通りで作成します。
サンプルコード
検索ボタンのイベントプロシージャは以下の通りです。
'****************************************** 'HTMLを取得する '****************************************** Private Sub cmd検索_Click() Dim s出発 As String Dim s到着 As String Dim w_URL As String Dim objIE As Object Dim strHtml As Variant Dim strSearch As Variant Dim wPosition As Long Dim wLen As Long Dim wStartPoint As Long Dim wEndPoint As Long Dim i As Integer '入力漏れがある場合は処理しない。 If Nz(Me!txb出発, "") = "" Or _ Nz(Me!txb到着, "") = "" Then Exit Sub '文字コードをUTF-8に変換 s出発 = UrlEncodeUtf8(Me!txb出発) s到着 = UrlEncodeUtf8(Me!txb到着) 'Yahoo!運賃検索URLを作成する w_URL = "http://transit.loco.yahoo.co.jp/search/result?from=" _ & s出発 & "&to=" & s到着 'objIEオブジェクトを作成します Set objIE = CreateObject("InternetExplorer.Application") 'インターネットエクスプローラは非表示にする objIE.Visible = False '指定したURLをセットします objIE.Navigate w_URL 'ページの読み込みが終わるまで待機する Do Until objIE.Busy = False '一旦処理を待機する(200ミリ秒) Sleep 200 Loop 'BodyのHTMLを取得する strHtml = objIE.Document.Body.InnerHtml '区間を取得する '最初の<h2>をセット strSearch = "<h2>" '文字数を取得 wLen = Len(strSearch) '区間の開始位置を取得 wStartPoint = InStr(strHtml, strSearch) + wLen '区間の終わりのタグ<span class="departure">をセット strSearch = "<span class=" & "" & "departure" & "" & ">" '区間の終了位置を取得 wEndPoint = InStr(strHtml, strSearch) '区間をテキストボックスにセットする Me!txbKukan = Mid(strHtml, wStartPoint, wEndPoint - wStartPoint) 'クリアする wEndPoint = 1 Me!txbRoot = Null '検索結果1ページ目(最大3経路)の運賃を取得する For i = 1 To 3 '[安]マークのタグ<span class="route-fare-on">をセット strSearch = "<span class=" & "" & "route-fare-on" & "" & ">" wLen = Len(strSearch) wStartPoint = InStr(wEndPoint, strHtml, strSearch) + wLen '[安]マーク料金(route-fare-on)を取得する If InStr(wEndPoint, strHtml, strSearch) <> 0 Then strSearch = "</span>" wEndPoint = InStr(wStartPoint, strHtml, strSearch) If Nz(Me!txbRoot, "") <> "" Then Me!txbRoot = Me!txbRoot & vbCrLf & _ "経路" & i & ":[安]" & _ Mid(strHtml, wStartPoint, wEndPoint - wStartPoint) Else Me!txbRoot = Me!txbRoot & "経路" & i & ":[安]" & _ Mid(strHtml, wStartPoint, wEndPoint - wStartPoint) End If Else '[安]マークが付いていない無い料金(route-fare-off)を取得する strSearch = "<span class=" & "" & "route-fare-off" & "" & ">" wLen = Len(strSearch) wStartPoint = InStr(wEndPoint, strHtml, strSearch) + wLen If InStr(wEndPoint, strHtml, strSearch) <> 0 Then strSearch = "</span>" wEndPoint = InStr(wStartPoint, strHtml, strSearch) If Nz(Me!txbRoot, "") <> "" Then Me!txbRoot = Me!txbRoot & vbCrLf & _ "経路" & i & ":" & _ Mid(strHtml, wStartPoint, wEndPoint - wStartPoint) Else Me!txbRoot = Me!txbRoot & "経路" & i & ":" & _ Mid(strHtml, wStartPoint, wEndPoint - wStartPoint) End If End If End If Next i Set objIE = Nothing End Sub
尚、運賃検索用のURLの作成に関する情報は前回のエントリー[Access2010のフォームにホームページを表示する方法~第2回(Yahoo!JAPANロコの路線検索を利用)]をご参考下さい。
標準モジュールに処理を待機させるためのAPIを設定する
Option Compare Database Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
VBAのポイント解説
-
IEオブジェクトを使う準備をします
サンプルコード30行目でIEオブジェクトを作成しています。 -
検索用URLをセットします
36行目でIEオブジェクトにNavigateプロパティを使い検索用URLをセットします。 -
ページの読み込みが終わるまで待機する
39行目から42行目までIEが検索結果を取得するまで処理を待機します。 -
BodyのHTMLを取得する
45行目で検索結果ページのBody部のHTMLをDocument.Body.InnerHtmlを利用して取得します。 -
区間をソースコードから抽出する
47行目から60行目までで区間のテキストを取得しています。区間はHTMLのソースコードを見ると最初のh2タグとspanタグに囲まれている事が分かります。サンプルソースではこのタグの位置をInStr関数を使って取得し、Mid関数で区間を抜き取っています。
-
運賃をソースコードから抽出する
67行目以降で最初の検索結果ページの3経路の運賃を取得していますが、運賃の表示で最安値の場合とそうでない場合、使われているspanタグのクラス(route-fare-onとroute-fare-off)が異なりますので、それぞれ参照するようにしなければいけません。区間同様に運賃の位置をInStr関数を使って取得し、Mid関数で抜き取ります。
以上、今回はIEオブジェクトを使ってHTMLを取得する方法について説明しました。
サンプルソースではYahoo!路線情報からHTMLソースを取得しましたが、Yahoo!側のサイト改変などにより内部構造が変わった場合は正常に動作しなくなる可能性も高いです。
そのような場合は、VBAも修正する必要がありますのでご了承ください。
関連エントリー
HTMLソースを取得するならXMLHTTPオブジェクトを使う方法がおすすめ!
IEオブジェクトを使わずにXMLHTTPオブジェクトを使ってYahoo!路線情報のHTMLソースを取得する方法について説明しています。
今回のサンプルファイルは以下のリンクからダウンロード可能です。