Skip to content

Instantly share code, notes, and snippets.

@katai5plate
Last active October 17, 2019 13:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save katai5plate/76b8b5207288acb5b1bf817f7c44836a to your computer and use it in GitHub Desktop.
Save katai5plate/76b8b5207288acb5b1bf817f7c44836a to your computer and use it in GitHub Desktop.
食べログのレビュー一覧から集計データを取得する方法

やり方

  1. 食べログの100件レビュー一覧を開く
    例: https://tabelog.com/XXXXX/XXXXX/XXXXX/XXXXX/dtlrvwlst/?lc=2
  2. DevToolsのコンソールを開く
  3. 下の makeJSON.js のコードを一文字残らず全部コピペしてEnter
  4. 集計データが表示されるので全文コピーする
  5. この変換サイトを開き、上のテキストボックスにペーストすると、
    下のほうにCSVが生成されるので、Download the entire CSV をクリックして100件の集計CSVをダウンロードする
  6. 100件レビュー一覧に次のページがあるなら、次のページで 1. の手順を行う。
  • このようにして集めたCSVデータから全平均を取ったりなどして使ってみよう

列名の説明

key desc
user_name ユーザー名
user_reviews ユーザーのレビュー投稿数
user_prifile/age ユーザーの年齢層
user_prifile/sex ユーザーの性別
user_prifile/address ユーザーの住まい
user_exp ユーザーがこれまで訪問した店の数
user_follows ユーザーのフォロー数
user_followers ユーザーのフォロワー数
rating_visits このユーザーがレビュー先に訪問した回数
rating_data/dinner/point 夕食の総合評価
rating_data/dinner/taste 夕食の料理と味の評価
rating_data/dinner/serv 夕食のサービスの評価
rating_data/dinner/mood 夕食の雰囲気の評価
rating_data/dinner/cp 夕食のコスパの評価
rating_data/dinner/drink 夕食の飲み物の評価
rating_data/average (夕食の総合評価+昼食の総合評価)÷2
rating_data/date このレビューで訪問した年月
rating_data/lunch/point 昼食の総合評価
rating_data/lunch/taste 昼食の料理と味の評価
rating_data/lunch/serv 昼食のサービスの評価
rating_data/lunch/mood 昼食の雰囲気の評価
rating_data/lunch/cp 昼食のコスパの評価
rating_data/lunch/drink 昼食の飲み物の評価
(()=>{
const result = [...document.querySelectorAll(".js-rvw-item-clickable-area")].map(d =>
[
["user_name", ".rvw-item__rvwr-name > a > .lev > span:nth-child(1)"],
["user_reviews", ".rvw-item__rvwr-name > a > .lev > span:nth-child(2)", x => Number(x.match(/\((.*?)\)/)[1])],
["user_profile", ".rvw-item__rvwr-profile", x => {const [age,sex,address] = x.split("・"); return{age,sex,address}}],
["user_exp", ".rvw-item__rvwr-balloon > p:nth-child(1) > span:nth-child(2)", x => x.match(/行ったお店(.*?)件/)[1]],
["user_follows", ".rvw-item__rvwr-balloon > p:nth-child(2) > span", x => Number((x.match(/フォロー(.*?)人/)[1]).replace(/,/g,""))],
["user_followers", ".rvw-item__rvwr-balloon > p:nth-child(2) > strong", x => Number((x.match(/フォロワー(.*?)人/)[1]).replace(/,/g,""))],
["rating_visits", ".rvw-item__visit-count-num.u-text-num", Number],
["rating_data", ".rvw-item__ratings", x => {
const n = x.replace(/\n/g,"");
const l = n.match(/昼の点数:(.*?)[ 料理・味(.*?) \|サービス(.*?) \|雰囲気(.*?) \|CP(.*?) \|酒・ドリンク(.*?)]/);
const d = n.match(/夜の点数:(.*?)[ 料理・味(.*?) \|サービス(.*?) \|雰囲気(.*?) \|CP(.*?) \|酒・ドリンク(.*?)]/);
const c = x => x === "-" ? null : x;
const [_l, lPoint, lTaste, lServ, lMood, lCp, lDrink] = !!l ? [...l].map(c) : [];
const [_d, dPoint, dTaste, dServ, dMood, dCp, dDrink] = !!d ? [...d].map(c) : [];
const f = (point,taste,serv,mood,cp,drink) => ({point,taste,serv,mood,cp,drink});
return {
...(!!l ? {lunch: f(lPoint, lTaste, lServ, lMood, lCp, lDrink)} : {}),
...(!!d ? {dinner: f(dPoint, dTaste, dServ, dMood, dCp, dDrink)} : {}),
average: ((!!l || lPoint === NaN ? lPoint : 0) + (!!d || dPoint === NaN ? dPoint : 0)) / ((!!l ? 1 : 0) + (!!d ? 1 : 0))
}
}],
["rating_date", ".rvw-item__date > p", x => x.match(/^(.*?)訪問/)[1]]
].reduce(
(p, [k, v, f = _ => _]) => ({
...p,
[k]: f(d.querySelector(v).innerText)
}),
{}
)
);
document.body.innerText = JSON.stringify(result);
console.log({result});
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment