【SeleniumBasic】地図の距離と時間を取得する【Excel】
- [記事公開]2023.04.21[最終更新]2024.05.21
- VBA
- ExcelVBA, SeleniumBasic
SeleniumBasic×Excel×Chromeで、Googleマップを検索し、目的地までの距離と時間を取得する方法を紹介します。
本当にやりたいことは別にあるのですが、その前段階として考えました。
このようなExcelシートがあります。出発地と目的地があらかじめ書いてあります。
この二つの地点間の距離と移動にかかる時間をGooglマップからルート検索で取得し、値をワークシートに持ってくるにはどうしたらよいか考えました。
私が考えたコードはこんな感じです。
Option Explicit
'ワークシートに表示する情報のヘッダ
Enum e
出発地 = 1
目的地
時間
距離
TheEnd = 距離
End Enum
'
'作成:野口香
'作成:2023/04/20
'
Public Sub GetMap()
'作業用シート
Dim sh As Worksheet
Set sh = ThisWorkbook.Worksheets(1)
'Seleniumを用意
Dim driver As Object
Set driver = CreateObject("Selenium.WebDriver")
'スクレイピングのお作法・・・wait時間
Const clWAIT As Long = 500
'Chromeをスタート
driver.Start "Chrome"
'ブラウザを最大サイズに
driver.Window.Maximize
'前回までの情報をクリアしておく
Const clHeader As Long = 2
sh.Range(sh.Cells(clHeader + 1, e.時間), sh.Cells(sh.Rows.Count, e.TheEnd)).ClearContents
'GoogleMapのURL
Const cstUrl As String = "https://www.google.co.jp/maps/dir///@36.3911651,139.0625882,17.98z/data=!4m2!4m1!3e0"
driver.Get cstUrl
driver.Wait clWAIT
'Loop開始前、準備
Dim ii As Long, lRow As Long
Const cstStart As Long = 3
lRow = sh.Cells(cstStart, e.目的地).End(xlDown).Row
If lRow = sh.Rows.Count Then
lRow = cstStart
End If
'出発地
Dim el As Object
For ii = cstStart To lRow
Set el = driver.FindElementByXPath("//*[@id=""sb_ifc50""]/input")
el.Clear
driver.Wait clWAIT
el.SendKeys sh.Cells(ii, e.出発地).Value
driver.Wait clWAIT
'目的地
Set el = driver.FindElementByXPath("//*[@id=""sb_ifc51""]/input")
el.Clear
driver.Wait clWAIT
el.SendKeys sh.Cells(ii, e.目的地).Value
driver.Wait clWAIT
'検索ボタンをクリック
driver.FindElementByXPath("//*[@id=""directions-searchbox-1""]/button[1]").Click
driver.Wait clWAIT * 10 '少し長めに待つ
'時間を取得
sh.Cells(ii, e.時間).Value = driver.FindElementByXPath("//*[@id=""section-directions-trip-0""]/div[1]/div[1]/div[1]/div[1]/span[1]").Text
driver.Wait clWAIT
'距離を取得
sh.Cells(ii, e.距離).Value = driver.FindElementByXPath("//*[@id=""section-directions-trip-0""]/div[1]/div[1]/div[1]/div[2]/div").Text
driver.Wait clWAIT
Next ii
'終了
driver.Close
'オブジェクト解放
Set sh = Nothing
Set driver = Nothing
Set el = Nothing
'終了メッセージ
MsgBox "終了"
End Sub
実行すると、こんな結果となりました。
注意点です。
今回有料道路を使う設定にしてあるので、検索結果には有料道路を利用した場合も出力されています。
有料道路を使わない設定にしたい場合は、チェックボックスをチェックする必要があります(が、今回のコードでは実装していません)。
今回コードを実験していて何度かぶつかったのが、要素を特定するXPathにずれがあることです。
出発地のIDを”sb_ifc50“で今回は実装しましたが、”sb_ifc51“となっているブラウザもありました。理由は不明です。Googleアカウントでログインしていると異なる可能性がありますが、未検証です。
使い道としては、大量のリストを渡されたときに、距離と時間から行き先の候補を絞る手助けにできるかと思います。
例では10件程度ですが、私が実際に渡されたのは100件近くありました。さすがにそれを1件ずつ手作業で検索するのは骨が折れますので、VBAで効率よくできないか考えました。
今回作ったものをZIPにしておいておきます。
https://kn-sharoushi.com/wp-content/uploads/2023/04/20230420getGoogleMap.zip
追記
閲覧者の1人から問合せがありまして、2024年5月21日現在、上記コードの72行目部分でエラーになることが確認できています。
原因は、Yahoo!地図サイトのHTML構文が変更になっているためです。
変更前のXPath
//*[@id=”section-directions-trip-0″]/div[1]/div[1]/div[1]/div[1]/span[1]
変更後のXPath
//*[@id=”section-directions-trip-0″]/div[1]/div/div[1]/div[1]
最後の/span[1]がなくなっているようです。
いちいち昔作ったコードを直してあげ直すのも面倒なんで、この記事はこの記事のまま掲載しておきます(後日気が変わって記事を取り下げるかもしれませんが)。
そもそもスクレイピングにおけるエレメント取得は、「あし」(腐る)の早い生物(なまもの)だと思っているので、当時使えたコードが1年も経つと使えないのは仕方がないのかなと個人的には思っています。
どうしても使いたいという方は、72行目を直してから使ってください。その際、IDを囲む””はVBAではダブルで必要になりますので、ご注意を。
-
前の記事
重たいものを持たせる上限は 2023.04.20
-
次の記事
【InternetExplorer】地図の距離と時間を取得する【Seleniumなしで】【WebDriverなしで】 2023.04.24