営業時間取得アプリの設計 → 開発 → テストの計画を立ててみた
はじめに

22:21:45
営業時間を取得するアプリを作ってみたいと思った。
最初は、PythonのBeautifulSoup(BS)を利用して、
「〇〇 営業時間」
とGoogle検索した結果から営業時間のテキストを取得することを考えていた。
そこで、ChatGPTに相談し、設計・開発・テストの計画を整理してみた。
営業時間をpythonのbsでスクレイピングするアプリを作りましょう〇〇 営業時間とGoogle検索した結果の営業時間のテキストを取得します設計と開発とテストの計画を作成してください

入力した店舗名や施設名から営業時間を取得する。
結果として、スクレイピングだけではなくGoogle Places APIという選択肢があることも知ることができた。
アプリの目的
例えば、
成城石井 名古屋
と入力すると、
月曜日 7:00~23:00
火曜日 7:00~23:00
水曜日 7:00~23:00
...
のような営業時間を取得して表示する。
将来的にはCSVへの保存や、Django・Reactとの連携も視野に入れている。

設計
まずは以下の流れを想定した。
ユーザー入力
↓
検索キーワード生成
↓
検索結果取得
↓
BeautifulSoupで解析
↓
営業時間テキスト抽出
↓
画面表示

ディレクトリ構成のイメージは以下。
business-hours-scraper/
├── app.py
├── scraper/
│ ├── google_search.py
│ ├── parser.py
│ └── formatter.py
├── tests/
│ ├── test_parser.py
│ └── sample_google.html
├── output/
│ └── result.csv
└── README.md
役割を分割しておくことで、テストしやすくなる。

開発計画
まずは最小構成のプロトタイプを作る。
フェーズ1
検索結果から営業時間らしきテキストを取得する。
・検索キーワード生成
・HTML取得
・BeautifulSoup解析
・営業時間候補抽出
フェーズ2
営業時間の抽出精度を上げる。
営業時間
営業中
閉店時間
24時間営業
曜日別営業時間
などの表記に対応する。
フェーズ3
CSV出力機能を追加する。
keyword,business_hours,status
成城石井 名古屋,7:00~23:00,success
フェーズ4
API連携版へ移行する。
Google Places APIや他のAPIを利用することで、より安定したデータ取得を目指す。


テスト計画
単体テスト
営業時間抽出ロジックを検証する。
テスト例
営業時間 10:00~20:00 を抽出できる
24時間営業を抽出できる
営業時間が存在しない場合はNoneを返す

結合テスト
入力から保存までの一連の流れを確認する。
入力
↓
検索
↓
HTML取得
↓
営業時間抽出
↓
CSV保存
正常系・異常系の両方を確認する。

手動テスト
以下のような検索ワードで試す。
成城石井 名古屋
スターバックス 名古屋駅
ユニクロ 名古屋駅
刈谷市役所
chocoZAP 刈谷
複数パターンで動作確認を行う。

最初に作る完成系
コマンドラインで実行できる状態を目指す。
python app.py "成城石井 名古屋"
実行結果
検索キーワード: 成城石井 名古屋 営業時間
営業時間候補
7:00~23:00
まずはシンプルに動くものを作る。

方針
調査してみると、Google検索結果のスクレイピングは安定性に課題があることが分かった。
検索結果のHTML構造は変更される可能性があり、Googleの利用規約にも注意が必要である。
そのため、
「まずはスクレイピング版を作る」
↓
「Google Places API版へ移行する」
という方針が良さそうだと感じた。

Google places API
Google Places APIはGoogleが提供する場所情報取得APIである。
店舗名から以下のような情報を取得できる。
- 店舗名
- 住所
- 営業時間
- 電話番号
- 評価
- レビュー数
営業時間取得アプリとの相性が非常に良い。

Google places APIの処理の流れ
まず店舗名で検索する。
成城石井 名古屋
↓
店舗情報を取得
↓
place_id取得
↓
営業時間取得
という流れになる。


Pythonでは以下のようなコードで利用できる。

import requests
API_KEY = "あなたのAPIキー"
place_id = "取得したplace_id"
url = (
"https://maps.googleapis.com/maps/api/place/details/json"
)
params = {
"place_id": place_id,
"fields": "name,opening_hours",
"key": API_KEY,
}
response = requests.get(url, params=params)
data = response.json()
print(data)
Google places APIのメリット

スクレイピングと比較すると以下のメリットがある。
安定している
スクレイピング
HTML変更
↓
動かなくなる
Google Places API
JSON形式
↓
安定して取得できる
営業時間専用データが存在する
営業時間を推測する必要がない。
opening_hours
として提供される。
実務でも利用されている
API連携の経験はポートフォリオとしても価値が高い。
Google places APIは、無料ではない
Google Maps Platformは従量課金制となっている。
利用量に応じて料金が発生する。
料金については公式サイトを確認する。

https://mapsplatform.google.com/pricing/?utm_source=chatgpt.com
今後のステップ
今回整理した結果、以下の順番で進めるのが良いと感じた。
Step1
BeautifulSoup版を作る
学べること
- requests
- BeautifulSoup
- HTML解析
- 正規表現
Step2
Google Places API版を作る
学べること
- API連携
- JSON解析
- REST API
- 認証
Step3
Djangoと連携する
店舗名入力
↓
営業時間取得
↓
DB保存
Step4
Reactと連携する
検索画面
↓
営業時間取得
↓
一覧表示
営業時間取得アプリは、
- Python
- API
- Django
- React
を一通り学べる題材になりそうである。
まずは小さく動くものを作りながら、少しずつ発展させていきたい。


スクレイピングと利用規約について考える
営業時間取得アプリの開発を進める中で、スクレイピングと利用規約の関係についても調べてみた。
最初は、
「Googleで検索して営業時間を見るのと、Pythonで取得するのは同じではないのか?」
と思っていた。
しかし、Google側から見ると両者は異なる。
人間がブラウザで検索する場合は、
- 検索結果を表示する
- 必要な情報を確認する
という通常利用である。
一方、スクレイピングはプログラムが自動でアクセスを行う。
例えば、
- 数十件
- 数百件
- 数千件
と大量のアクセスを短時間で実行できる。
そのため、Google検索結果の自動取得や大量取得には利用規約上の制限が存在する。
また、HTML構造は予告なく変更されるため、
soup.find(...)
で取得できていた情報が突然取得できなくなることもある。
学習目的で数件のデータを取得し、
- requests
- BeautifulSoup
- HTML解析
を学ぶこと自体は良い教材になる。
しかし、サービスとして公開したり、継続運用したりする場合は別の視点が必要になる。
そこで将来的には Google Places API の利用を検討している。
APIであれば、
- 公式に提供されている
- 構造化されたデータを取得できる
- HTML解析が不要
- 保守性が高い
というメリットがある。
まずはスクレイピングでWebの仕組みを学び、その後APIへ移行することで、技術的な理解と実用性の両方を身につけていきたい。
23:07:36
コメントを残す