食べログとSNSの評価を比較してみた [その１]～ツイート取得・店舗選別～

# はじめに
Python初学者のまさやです！

皆様は、カフェやレストランの情報を何から取得していますでしょうか？
最近は、食べログなどのサイトだけではなく、SNSで確認される方もいるのではないでしょうか？

私は前職、中小企業のPRのお手伝いを行っていました。
お客様にはSNSでの情報発信の必要性も訴えてきましたが、それは本当に必要だったのでしょうか！？

今回はPythonの練習としてTwitterAPIにてツイートの取得。
食べログのスクレイピングを行い、評価の比較を行ってみました！！！

---

####環境設定
Python 3.7.2
Google Colaboratory
インストールした外部パッケージは都度コードの先頭に記載

---

以下4記事がまとめて3分で読める！
[<font color="LimeGreen">__[3分で読める] 食べログとSNSの評価を比較してみた～ショート編～__</font>](https://qiita.com/masaya_gg/items/e9dd362fa4aa3eaa56ba)

##簡単なあらすじ(リンク付き！)

- [<font color="LimeGreen">__(その1)ツイートの取得(SNSの調査)/カフェの選定__</font>](https://qiita.com/masaya_gg/items/c5f4301b13c2cf1bf844)<font color="Red">（本記事）</font>
TwitterAPIを活用し、東京23区内の人気カフェ/スイーツ店のツイートを取得
取得した店舗のうち、総ツイート数が200件を超えている店舗10店舗を選定。

- [<font color="LimeGreen">__(その2)ツイートの前処理__</font>](https://qiita.com/masaya_hashizaki/private/918d4efaa3ae97d45c27)
ツイートには取得したい感想(評価)の他に、公式アカウントや引用ツイート、
お土産ランキングなど不要なツイートを削除。

- [<font color="LimeGreen">__(その3)感情分析にてツイートを得点化__</font>](https://qiita.com/masaya_hashizaki/private/24d6a898312dc7e4a524)
「日本語評価極性辞書」と「単語感情極性値対応表」2つの辞書を活用し、得点の比較。
食べログの評価幅が[0~5]のため、正規化にて幅を[0~5]合わせる。

- [<font color="LimeGreen">__(その4)食べログ評価を取得/比較__</font>](https://qiita.com/masaya_hashizaki/private/89c08a49d76393ca4438)
食べログの評価を取得し、評価の分布をグラフ化。
先ほど取得したツイートの点数との比較を行う。

#1.ツイートデータの取得(2021年09月20日~27日/1週間分)

<details><summary><font color="Red">__コード一覧はこちら__</font></summary><div>

```python
#各種必要ライブラリ等のインストール
!pip install requests_oauthlib

from requests_oauthlib import OAuth1Session
import json
import datetime, time, sys
import tweepy
import pandas as pd
import re
import csv
import urllib.request
import zipfile
import traceback

#利用申請が承認された後のAPIキーの設定
consumer_key = 'xxxxxxxxxxxxxxx'
consumer_secret = 'xxxxxxxxxxxxxxx'
access_token ='xxxxxxxxxxxxxxx'
access_secret = 'xxxxxxxxxxxxxxx'

session = OAuth1Session(consumer_key, consumer_secret, access_token, access_secret)
url = 'https://api.twitter.com/1.1/search/tweets.json'

tweet = []
list_text = []
list_id = []
list_user = []
list_created_at = []
list_favorite = []
list_retweet = []
list_followers = []

#ツイートのタイムラインを取得する
df = pd.DataFrame(columns=['text','id','name','created_at','favorite_count',"retweet_count","followers_count"])

try:
  def get_tweets(query):
    global df
    mid = -1
　　
    #1度に100件のツイートを取得する
    while True:
      res = session.get(url, params = {'q':targets, 'count':100, 'max_id': mid})
      res_text = json.loads(res.text)

    　#取得したツイートをそれぞれのリストに格納
      for tweet in res_text['statuses']:
        list_text.append(tweet['text'])
        list_id.append(tweet['id'])
        list_user.append(tweet['user']['screen_name'])
        list_created_at.append(tweet['created_at'])
        list_favorite.append(tweet['favorite_count'])
        list_retweet.append(tweet["retweet_count"])
        list_followers.append(tweet["user"]["followers_count"])
      
  　　#リストのデータをDataFrameに格納
      df_tmp = pd.DataFrame(columns=['text','id','name','created_at','favorite_count',"retweet_count","followers_count"])
      df_tmp = df_tmp.assign(text=list_text, id=list_id, name=list_user, created_at=list_created_at,favorite_count=list_favorite,retweet_count=list_retweet,followers_count=list_followers)
      df = pd.concat([df,df_tmp])

　　　#一定数ツイートを取得したのち、再度続きからツイートを取得するために
      if "next_results" in res_text["search_metadata"].keys():
        next_url = res_text['search_metadata']['next_results']
        pattern = r".*max_id=([0-9]*)\&.*"
        ite = re.finditer(pattern, next_url)
        for i in ite:
            mid = i.group(1)
            break
      else:
        traceback.print_exc()
        break

　　　#500件まで情報を取得したら終了
      print(len(tweet))
      if len(tweet) >= 500:
        break

    return df

  #xに検索する店舗名を記入
　#-RTでリツイートを除くツイートを取得
  targets = [u'xxxx　-RT']
  df = pd.concat([df,get_tweets(targets)])

except:
  print('error')
  traceback.print_exc()
else:
  print('no_error')
finally:
  print('finish')
```
</div></details>


####TwitterAPI利用登録
まずは、TwitterAPIを利用するため登録。
以下のサイトを参考にしました。
[2021年度版 Twitter API利用申請の例文からAPIキーの取得まで詳しく解説](https://www.itti.jp/web-direction/how-to-apply-for-twitter-api/)


####ツイート取得

```
for tweet in res_text['statuses']:
        list_text.append(tweet['text'])
        list_id.append(tweet['id'])
        list_user.append(tweet['user']['screen_name'])
        list_created_at.append(tweet['created_at'])
        list_favorite.append(tweet['favorite_count'])
        list_retweet.append(tweet["retweet_count"])
        list_followers.append(tweet["user"]["followers_count"])

      df_tmp = pd.DataFrame(columns=['text','id','name','created_at','favorite_count',"retweet_count","followers_count"])
      df_tmp = df_tmp.assign(text=list_text, id=list_id, name=list_user, created_at=list_created_at,favorite_count=list_favorite,retweet_count=list_retweet,followers_count=list_followers)
      df = pd.concat([df,df_tmp])
```
今回取得するツイート情報は下記

|取得情報      |用途        |
|:-----------------|:------------------|
|ツイート文書(text)      |感情分析のため         |
|ユーザーID(id)    |重複ツイート検出のため       |
|ユーザー名(name)  |重複ツイート検出のため|
|ツイート日(created_at)  |正しく1週間分取得できているか確認するため   |
|いいね数(favorite_count)  |今後の展望     |
|リツイート数(retweet_count)  |今後の展望    |
|フォロワー数(followers_count)|今後の展望|

####ツイート取得条件
```
while True:
      res = session.get(url, params = {'q':targets, 'count':100, 'max_id': mid})

      if "next_results" in res_text["search_metadata"].keys():
        next_url = res_text['search_metadata']['next_results']
        pattern = r".*max_id=([0-9]*)\&.*"
        ite = re.finditer(pattern, next_url)
        for i in ite:
            mid = i.group(1)
            break

      else:
        traceback.print_exc()
        break

      print(len(tweet))
      if len(tweet) >= 500:
        break

    return df
```
ツイートを取得するにあたり、TwitterAPIにより課せられたルールとして、
1度に取得できるツイート数や、リクエスト回数などが定められています。
今回は1回で100件のツイートを取得し、500件まで取得を続けるコードになります。

また、100件取得した場合、
再度最新のツイートを取得せず、続きから始めるようmax_idを設定し取得しました。

####取得した感想
![PnjVl78ORnK3LD91633929221_1633929239.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1971455/c1058042-1efe-640e-fb8b-3cc96ac99a4f.png)

- ユーザーID/ユーザー名はどちらかのみで十分
- textにはSNSならではの顔文字や文脈が多く、正しく感情分析が可能か不安。
- 「-RT」でリツイートを除外することはできたが、引用ツイートが意外と多かった。
- 今後、ツイートした人だけではなく、「フォロワー」と「いいね数」、「リツイート」などインフルエンサーポイントを追加して、ツイートに反応した人の点数も加点してオリジナルランキングも作成してみたい。

#2.店舗の選別
####店舗の検索
取得できるツイートは1週間以内と限られています。
そのため、1週間のうちにツイート数が多いカフェまたはスイーツ専門店を探します。
探す方法は、食べログにて

- 「東京/カフェ・喫茶」ランキング上位100位
- 「東京/カフェ・喫茶」口コミ数上位100位
- カフェ百名店2021/2020

の中からツイート数が多い上位10店舗のツイートデータをを使用。

__～リンクはこちら！～__
[ランキング上位100位](https://tabelog.com/tokyo/rstLst/cafe/?Srt=D&SrtT=rt&sort_mode=1&sk=%E3%82%AB%E3%83%95%E3%82%A7%E3%83%BB%E5%96%AB%E8%8C%B6&LstReserve=0&LstSmoking=0&svd=20210929&svt=2030&svps=2)
[口コミ上位100位](https://tabelog.com/tokyo/rstLst/cafe/?Srt=D&SrtT=rvcn&sk=%E3%82%AB%E3%83%95%E3%82%A7%E3%83%BB%E5%96%AB%E8%8C%B6&LstReserve=0&LstSmoking=0&svd=20210929&svt=2030&svps=2)
[カフェ百名店2021](https://award.tabelog.com/hyakumeiten/cafe)
[スイーツ百名店2020](https://award.tabelog.com/hyakumeiten/sweets_tokyo/2020?sort=ranking)

![alt](https://tblg.k-img.com/images/restaurant/image/contents_bnr_hyakumeiten2021_320x180_cafe_japan.png)

####検索方法
検索で使用するコードは1.ツイートデータの取得を使用します。
targetsに記入する店舗名は正式名所ではなく、<font color="Red">ツイートされやすそうな名前</font>で検索します。

__記入名__
例)
スターバックス コーヒー ジャパン: Starbucks Coffee Japan
→<font color="Red">「スタバ」</font>　や　<font color="Red">「スターバックス」</font>などのツイート数が多いワードを採用　


__例外__
検索した際、カフェの情報ではないものがたくさん取得される店舗に関しては対象外とします。
例）
パティスリー
→「パティスリー リョーコ」/「パティスリー・パリセヴェイユ」/「パティスリー プレジール」
などパティスリーでは情報が混在し、
フルネームではツイート数が激減してしまいました。

####ノミネート10店舗
上記にてツイート数が多かった10店舗は以下になります！

| 店名       |検索名        |取得ツイート数        |
|:-----------------|:------------------|:------------------|
|キル フェ ボン       |キルフェボン         |2385      |
|ピエール・エルメ     |ピエールエルメ       |996        |
|ブルーボトルコーヒー  |ブルーボトル   |731         |
|ケンズカフェ東京   |ケンズカフェ   |647                 |
|マリアージュフレール  |マリアージュフレール     |527          |
|ひみつ堂    |ひみつ堂     |419         |
|資生堂パーラー|資生堂パーラー |395   |
|和栗や  |和栗や     |326   |
|アンリ・シャルパンティエ  |アンリ・シャルパンティエ |292|
|銀座ウエスト  |銀座ウエスト   |268  |

- 200~300件程度の候補から上位10店舗を抽出！！！
- 反省点として、500件までと定義したコードがうまく作動しておらず、ツイート数にばらつきがでてしまった。今後、原因に関しても考えてみたい。
- ツイート数が予想より少なく、200件を超える店舗がほぼなかった。やはり、カフェなどの情報をSNSにアップする際、Twitterではなく、Instagramが選ばれる傾向がある予想。
- 店舗名を決める際、「パティスリー」などの文言は、他店舗と混合するためSNSには不向き。また、英語表記の店舗名は外国人の名前やツイートと混合してしまい、こちらも不向きだと思った。

～季節に関して～

- 「ひみつ堂」は人気かき氷屋。夏には3時間以上並ぶことも。まだまだ、残暑が厳しく10月を前にしてもツイートは多かった。
- 和栗やは栗の季節を目前に「食べたい」など期待に対するツイート多数。栗が収穫できない季節には店を閉めるほど徹底された品質管理にも"限定感"が相まってツイート数が多かったと推測。

__続く！__
[__[その2]__](https://qiita.com/masaya_hashizaki/private/918d4efaa3ae97d45c27)
3.ツイートデータの前処理