retarfiの日記

自然言語処理などの研究やゴルフ、音楽など。

本当に簡単なゴルフ場を探す

ゴルフを始めてあまり経っていない人とラウンドに行く機会が増えました。
ゴルフ場を予約するときに気になってきたのが、コースの難易度です。
特に始めたての頃は、コースが難しすぎると大変です。
(もちろん自分のスコアも良くはないのですが)
なので、なるべく簡単なコースを探そうと思って調べるものの、
巷のコースを紹介しているページでは、本当に簡単なのか?というコースもあったりします。

そこで今回はGDOゴルフ予約の情報を集約して、データから易しいコースで、お値段も高すぎないコースを探せるようにしたいと思います。
GDOの口コミでは、フェアウェイの広さや難易度の他に、GDOスコアから収集した各スコア帯(96-105など)の人の平均スコアを見ることができます。
これらを見れば、より定量的にコースの難易度を比較できます(各コースに来る各スコア帯の人の本当の実力の分布が同一であるという仮定は必要ですが)。

やること自体は複雑ではありません。
手順としては、

  1. ゴルフコースの一覧を作成する
  2. 各ゴルフコースについて様々な情報を集める

という流れです。

まず1つ目のゴルフコースの一覧作成について。
GDO予約から各地域の都道府県などを指定して検索すると、以下のようなURLで検索されていることがわかります。

https://reserve.golfdigest.co.jp/s/search/calendar/?region=千葉県&start_time=8時台&start_time=9時台&start_time=10時台&exclude=ハーフプレーを除く&exclude=1人予約を除く&exclude=ジュニアプランを除く&exclude=コンペプランを除く&exclude=オープンコンペを除く&exclude=ナイタープレーを除く&month=9&day=1&during=31&sort=course_rate_total_desc&rows=60

この例では

  • 千葉県で
  • 8,9,10時台のスタートで
  • ハーフプレー、1人予約、ジュニアプラン、コンペプラン、オープンコンペ、ナイタープレーを除いたものを
  • 9月1日から
  • 31日間について
  • 高評価順に
  • 60件

検索しています。
このように、URLのクエリを変えることで様々な条件で検索ができます。
&=:/?を変換しないで行うURLエンコードは必要です。
Pythonならurllib.parse.quote(<変換したいURL>, safe="&=:/?")で実現できます。
使えるクエリの種類については、検索画面のプルダウンやチェックをいろいろいじればわかります。
60件より多い件数の場合、&page=2などを追加すると適当なページを表示できます。
このようにして各ゴルフ場を表示し、これらのリンクから各ゴルフ場の名前、id(URLの末尾)、ICからの距離などを取得します。
実際の抽出はPythonではrequests+BeautifulSoupなどでできます。

次に、各ゴルフ場のidがわかれば、口コミや予約カレンダー、詳細情報のページをスクレイピングすることで情報を集められます。
例えば赤羽ゴルフ倶楽部(id:360101)であれば、URLはそれぞれ

のようになっています。
各ゴルフ場の、各ページから抽出すれば完成です。
口コミページを見ると一見seleniumなどを使わないと無理そうですが、Pythonのrequestsでも収集できました。
実際のコードについては公開しませんが、8月19日の夜時点で、9月の予約状況をもとに検索した結果をスプレッドシートにまとめましたので公開します。
価格帯やレビュー、平均スコアは時間とともに変わると思いますが、ある程度参考になると思います。
範囲は私が行きやすい県として栃木県、群馬県茨城県、埼玉県、千葉県、東京都、神奈川県に限定しています。
列数が非常に多くなっていますので、適度に非表示にしながらの方が見やすいと思います。

docs.google.com

GitHub Actionsでワークフロー化すれば定期的に更新できるかと考えましたが、
スプレッドシートを更新するのにGCP周りで設定が必要そうなので一旦はこれで置いておきます。