5万件規模の店舗情報サイトを短期間で構築する方法
立ち飲みドットコムの全国店舗データ構築で確立した、PC取得・CSV逐次保存・営業時間構造化・REST API一括投入・紹介文生成・代表写真処理までの標準フローです。ラーメンなど他業種にも流用できます。
1. WordPress上で1店舗ずつ作らない
店舗母集団確保 → PC詳細取得 → CSV逐次保存 → 正規化 → 曜日別営業時間 → JSON → REST API一括登録 → 紹介文 → 代表写真 → 不足分補完、の順で処理します。
2. データソースを統一する
立ち飲みドットコムでは食べログを基本データソースに統一。取得できない項目を別サイトで全件補完せず、同一構造を優先します。
3. 全店舗マスターを作る
掲載順、店舗名、食べログURL、Tabelog ID、検索結果ページ番号を保存し、取得可能なら最寄駅・ジャンル・評価・口コミ件数・予算も保存します。
4. PCで店舗詳細を取得する
店舗名、住所、電話、営業時間、定休日、予算、支払方法、最寄駅、予約可否、席数、喫煙情報、オープン日、確認元URL、代表写真候補を処理します。
5. 1店舗ごとにCSVへ逐次保存する
取得状態、取得日時、エラー内容、再取得要否も保存し、停止後は未取得レコードから再開します。
6. 営業時間を曜日別に構造化する
"hours": {
"monday":"17:00-23:00",
"tuesday":"17:00-23:00",
"wednesday":"定休日"
}文章だけでなく構造化データを持たせ、営業中/営業時間外を自動判定します。
7. 店舗状態と現在営業中判定を分ける
休業・閉店など店舗自体の状態と、現在時刻の営業中/営業時間外を分離します。
8. ラーメンの2部制営業時間
"monday":["11:00-14:30","17:30-22:00"]
昼・夜の2部制や通し営業、昼のみ、夜のみ、定休日を同じ構造で扱えるようにします。
9. WordPress投入前にデータを完成させる
title、address、postal_code、reservation_contact、nearest_station、walk_minutes、price_note、payment_methods、reservation_availability、seat_count、smoking、open_date、business_hours、closed_days、hours、source_url等へ正規化します。
10. REST APIで一括投入する
$json = Get-Content "C:\data\shops.json" -Raw -Encoding UTF8 Invoke-RestMethod -Uri "https://example.com/wp-json/your-api/v1/bulk-upsert" -Method POST -Headers $headers -ContentType "application/json; charset=utf-8" -Body $json
11. 大阪1,200店舗での実績
基本データは100件単位で登録し、failed = 0を最重要確認項目としました。
12. 紹介文は事実データから独自生成する
最寄駅、予算、予約可否、席数、営業時間、支払方法、喫煙情報などから独自文を生成。大阪では1,200件を400件×3で更新しました。
13. 紹介文のパターンを分散する
同一テンプレートの反復を避け、書き出し・語順・使用項目を分散します。
14. 写真は1店舗1枚を基本にする
初期構築では代表写真1枚に限定し処理量を抑えます。第三者写真の公開利用は著作権・ライセンス・利用条件を確認します。
15. 写真投入は分割する
画像取得、メディア保存、サムネイル生成、アイキャッチ設定は重いため、立ち飲みでは200件単位を標準としました。
16. エラー時は無条件で再実行しない
最終成功番号、未処理件数、実反映件数、タイムアウトか失敗か、再実行の必要性を確認します。
17. アクセス制限を回避する処理は行わない
CAPTCHA、アクセス拒否、レート制限等が発生した場合は回避・突破せず停止して確認します。高速化は取得済みスキップ、必要ページ限定、逐次保存、エラー分のみ再処理で実現します。
18. 取得とWordPress登録を分離する
PC取得 → CSV → 確認・整形 → JSON → WordPress投入、と分離し、WordPress側の障害でも元データを失わないようにします。
19. 次回は取得時点で完成形に近づける
ラーメンでは基本情報、曜日別・2部制営業時間、定休日、営業判定用データ、代表写真1枚、確認元URL、取得日時、取得状態まで最初から同一レコードで管理します。
20. 高速化の要点
母集団固定、逐次保存、未取得から再開、曜日別営業時間、複数時間帯、事実ベース紹介文、代表写真1枚、REST API一括投入、失敗分のみ再処理、差分更新が基本です。
21. 大量処理で分かったこと
PC速度以上に、同じ処理を繰り返さない仕組みが重要でした。取得済み判定、途中再開、エラー記録、CSV逐次保存、JSON固定、写真処理分離が効きます。
22. WordPressも大量データ前提で設計する
カスタム投稿、地方・都道府県、検索、現在地、地図、営業時間判定、店舗登録・修正、口コミ、投稿写真、訪問記録、ランキングを店舗ID中心で連携します。
23. 完成済みエンジンを他業種へ流用する
立ち飲みで完成した全国店舗検索の基本構造を流用し、ラーメンでは2部制営業時間など業種固有部分だけを追加します。
24. 標準フロー
母集団確定 → マスター保存 → 詳細+代表写真候補取得 → CSV逐次保存 → 曜日別・複数時間帯化 → 正規化 → JSON → REST API → 紹介文 → 写真 → エラー分再処理 → 差分更新。
25. 重要なのは取得速度だけではない
10,000件中9,000件で止まっても9,001件目から再開できる設計の方が、単純な高速化より大規模処理では重要です。
26. 写真・文章の公開利用は別に考える
取得できることと公開利用できることは別です。写真は権利・利用条件を確認し、紹介文は他サイト本文を複製せず事実データから独自生成します。
27. 初回完成後は差分更新へ移行する
新規店舗、掲載終了候補、情報変更店舗、取得エラー店舗を前回マスターと比較し、変更対象だけを更新します。
まとめ
大量店舗サイトは1店舗ずつ作るのではなく、データ処理システムとして設計する。取得元と形式を統一し、PCで取得・保存・整形し、完成データだけをWordPressへ投入します。営業時間は曜日別・複数時間帯へ構造化し、紹介文は事実から独自生成、写真は利用条件を確認して扱います。初回構築後は差分更新へ移行します。