獺祭の正規販売店の一覧マップを作る
獺祭を作っている旭酒造が「頼むから(正規販売店で)正規の値段で買ってくれ」という広告を出したらしい。その広告を見て思った。
「よし。正規販売店で買ってやろうじゃないか…ただし、正規販売店のリストをGoogleマップでくれ!広告にある店名のリストから、最寄り店を目grepで探せるわけがないんじゃ!」
というわけで、旭酒造のWebページから正規販売店の一覧マップを作れるようにしました。
やり方
CSVをダウンロードした後の手続きはGoogleマイマップの公式ドキュメントを参照した方が親切です。
- ここでCSVファイルを入手します。
- Googleマイマップのページに行き、新しいマップを作ります。
- インポートメニューから1で入手したCSVファイルをインポートします。どの列が住所でどの列がタイトルかを聞かれるので、適切に選んでください
- 完成
やったこと
前述のとおり、Googleマイマップはタイトルと住所が含まれたCSVファイルからマップを作れるらしい。というわけで、店名と住所が含まれたCSVを生成することが今回の目標です。 言語はJavascriptに決定。理由はJSだとHTMLのデータの抽出が楽そうだから。最近は頻繁に触っているし。(スクレイピングツールを使えばいいじゃんというツッコミは無しの方向で)
とりあえず、Webページの形式を確認しに行く。
嫌な予感がするぞ…
はい。というか、まともなフォーマットだったらExcelで完結するんですけどね。(いや、このままでもExcelでいける気がする。) 一つしか要素がないTRタグを取り除いて、二ついっぺんに処理するといい感じになりそう。
const getPage = (region)=>{ return new Promise((resolve,reject)=>{ const request = new XMLHttpRequest(); request.open('GET', `http://www.asahishuzo.ne.jp/store/ja/${region}`); request.responseType = 'document'; request.addEventListener('load', (e)=>{ if (request.status === 200) { const doc = request.responseXML; const trs = doc.querySelectorAll('tbody > tr'); const filteredTrs = []; for (let i = 0; i < trs.length; i++) { if (trs[i].childNodes.length > 1) { filteredTrs.push(trs[i]); } } const map = new Map(); for (let i = 0; i < filteredTrs.length; i += 2) { map.set(filteredTrs[i].childNodes[1].innerText, filteredTrs[i + 1].childNodes[1].innerText); } resolve(map); } }); request.addEventListener('error', (e)=>reject()); request.send(); }) }; const regions = ['hokkaidou', 'touhoku', 'kantou', 'cyubu', 'kansai', 'cyugoku', 'shikoku', 'kyushu', 'okinawa']; Promise .all(regions.map(getPage)) .then((maps) => { let resultMap = new Map(); for (let i = 0; i < maps.length; i++) { resultMap = new Map([...resultMap, ...maps[i]]); } document.open(); resultMap.forEach((name, address) => { document.write(`${name},${address}<br/>`); }); document.close(); });