【IT】JavaScriptで食べログの店舗情報を取得する方法/Webスクレイピング/csvデータ #食べログ #JavaScript
導入
blogさぼってましたが、IT関連は自身の備忘のために記録したいと思います。
JavaScriptで食べログの店舗情報をWebスクレイピングする方法について記録します。
HTMLのxpathの勉強のためにやってみました。
食べログのAPIサービスは停止しているとのことで、店舗情報を取得するには下記のように地道にWebスクレイピングするしかないようです(?)(2019/04現在)。
目次・流れ
No | タイトル |
---|---|
1 | 概要/事例/目的 |
2 | コード/実行結果 |
3 | 解説・補足 |
4 | ソース改良版(2019/04/20) |
・JavaScript/CSS/HTMLの違いを理解していること
・JavaScriptの基本文法について理解していること
・JavaScriptは完全独学のため、コーディング規約等遵守していないです。
<実行環境>
・OS:Windows10
・ブラウザ:Chrome バージョン: 73.0.3683.103(Official Build) (64 ビット)
概要/事例/目的
テストで利用するDBにサンプルデータを登録しようと思ったのですが
実データっぽいものがないかな?と思い、食べログのデータを抽出してみました。
下記の赤枠(※)の箇所に関して、カンマ区切りのデータを抽出するscriptを記載しました。
※店名,場所,ジャンル,点数,口コミ数(銀座のお店を検索しました。)
コード/実行結果
実行画面
実行方法は下記の通り。gifをご参考ください。
コード
スマホだと意味不明だと思うので、PCでご覧ください。
/* 初期化*/ var work = ''; var result = 'No,店名,場所,ジャンル,点数,口コミ数\r\n'; /*出力header情報*/ /*●変数 ・shop_name:店名(class名で取得) ・shop_summry:概要(class名で取得) ・shop_rate:点数(class名で取得 ※点数が表示されない場合がある。要素の個数に応じて処理を分岐。) ・shop_reviews:口コミ数(class名で取得) ※class名やHTMLの構造は食べログサービスによって変更されるものであり、動作を常に保証するものではありません。 */ var shop_name = document.getElementsByClassName("list-rst__rst-name-target cpy-rst-name"); var shop_summry = document.getElementsByClassName("list-rst__area-genre cpy-area-genre"); var shop_rate = document.getElementsByClassName("list-rst__rate"); var shop_reviews = document.getElementsByClassName("list-rst__rvw-count-num cpy-review-count"); for(var i = 0; i < shop_name.length; ++i){ /*点数エリアの要素数*/ var val_area_cnt = document.getElementsByClassName("list-rst__rate")[i].children.length; /*点数が表示される場合*/ if ( val_area_cnt == 2){ work = (i+1) +','+ shop_name[i].innerText +','+ ((shop_summry[i].innerText).replace(' / ',',')).trim() +','+ shop_rate[i].children[0].innerText +','+ shop_reviews[i].innerText + '\r\n'; result = result + work; /*点数が表示されない場合*/ } else if (val_area_cnt == 1){ work = (i+1) +','+ shop_name[i].innerText +','+ ((shop_summry[i].innerText).replace(' / ',',')).trim() +','+ 'No Score' +','+ shop_reviews[i].innerText + '\r\n'; result = result + work; } };
実行結果
食べログは1ページごとに20店舗表示されるので、2ページ以降もページ遷移して、地道に取得してみてください。
No,店名,場所,ジャンル,点数,口コミ数 1,支那麺 はしご 本店,銀座駅 251m,担々麺、ラーメン,3.59,857 2,グルガオン,銀座一丁目駅 33m,インド料理、インドカレー,3.64,760 3,銀座 久兵衛 銀座本店,新橋駅 357m,寿司,3.79,718 (~省略~) 18,銀座千疋屋 銀座本店 フルーツパーラー,銀座駅 25m,フルーツパーラー、パフェ、ケーキ,3.59,392 19,銀座 しまだ,新橋駅 375m,割烹・小料理、魚介料理・海鮮料理、居酒屋,3.92,371 20,インペリアルバイキング サール,日比谷駅 300m,バイキング、洋食・欧風料理(その他)、西洋各国料理(その他),3.63,367
下記のように、textデータを整形してエクセルに表示してみると、結構壮観です。
解説
<操作>
- getElementsByClassName("Class名")メソッド
- 返り値:HTMLCollection ※配列(Array)ではないです。
上記メソッドでHTMLCollection[0]~[19](合計20店舗分)を取得できます。
本HTMLCollectionをfor文でLoop処理して、innerTextを取得しているだけです。
<補足>
【場所とジャンル】は' / '(スラッシュ)で1つのデータとして結合されている(例:「銀座駅 251m / 担々麺、ラーメン」)ので、 カンマ区切りに置換してます。また、前後の半角スペースを削除してデータクレンジングしてます。
食べログに点数が表示されない場合があるため、「No Score」と表示するようにしてます。 異常値データが混在しており、どこまでプログラムで場合分けするか悩ましいですね。
大前提ですが、class名やHTMLの構造は食べログサービスによって変更されるものであり、本scriptの動作を常に保証するものではありません。 ご注意ください。
以上。
【婚活】非モテ・エンジニア流!食べログでデートに使えるお店を知る3つのコツ - 仕事と婚活と私~ITエンジニアの末路~
ソース改良版(2019/04/20)
■修正内容
・夜の価格帯・昼の価格帯の追加
・分岐のコードの共通化
/* 初期化*/ var work = ''; var result = 'No,店名,場所,距離,ジャンル,点数,口コミ数,夜価格(From),夜価格(To),昼価格(From),昼価格(To)\r\n'; /*出力header情報*/ /*●変数 下記class名で取得 ・shop_name:店名 ・shop_summry:概要 ・shop_rate:点数 ・shop_reviews:口コミ数 ・shop_budget_dinner:夜の価格帯 ・shop_budget_lunch:昼の価格帯 ※class名やHTMLの構造は食べログサービスによって変更されるものであり、動作を常に保証するものではありません。 */ var shop_name = document.getElementsByClassName("list-rst__rst-name-target cpy-rst-name"); var shop_summry = document.getElementsByClassName("list-rst__area-genre cpy-area-genre"); var shop_rate = document.getElementsByClassName("list-rst__rate"); var shop_reviews = document.getElementsByClassName("list-rst__rvw-count-num cpy-review-count"); var shop_budget_dinner = document.getElementsByClassName("c-rating__val list-rst__budget-val cpy-dinner-budget-val"); var shop_budget_lunch = document.getElementsByClassName("c-rating__val list-rst__budget-val cpy-lunch-budget-val"); for(var i = 0; i < shop_name.length; ++i){ /*点数エリアの要素数*/ var val_area_cnt = document.getElementsByClassName("list-rst__rate")[i].children.length; work = (i+1) +','+ shop_name[i].innerText +','+ shop_summry[i].innerText.replace(' / ',',').trim().replace(' ',','); /*点数が表示される場合*/ if ( val_area_cnt == 2){ work = work +','+ shop_rate[i].children[0].innerText; /*点数が表示されない場合*/ } else if (val_area_cnt == 1){ work = work +','+ 'No Score' ; } work = work +','+ shop_reviews[i].innerText.replace(' - ','0') +','+ shop_budget_dinner[i].innerText.replace(/¥/g,'').replace(/,/g,'').replace('~',',') +','+ shop_budget_lunch[i].innerText.replace(/¥/g,'').replace(/,/g,'').replace('~',',') + '\r\n'; result = result + work; };
某4人兄弟バンドに関して宣伝させてください。
2019年内に私の好きなバンド【SaToMansion】が解散の危機を迎えています!
マジで勘弁して欲しいけど。彼らも本気ということです。
彼らの曲を聴いて下さい。マジで掛値なしにかっこいい。
そしてYou Tubeのチャンネル登録をお願いします!
我らが百獣の王、
— SaToMansion【公式】 (@SaToMansion_off) 2019年3月13日
武井壮さんからの指令で
サトマンTube、年内に
チャンネル登録数10000人達成!
出来なければ解散という事になりました!
詳しくはこちらの動画を↓https://t.co/VI0zRHlYPY
昨日1000人を突破しましたが、あと9000人…皆さまのご協力が必要です!
ぜひ拡散の程お願いします!🙇♂️ pic.twitter.com/ufGqkWXX2K