RIZEの歌詞に出てくる固有名詞を分析してみる

# はじめに
The BONEZ - Straight Up feat. Kj / THE FIRST TAKE　がサイコーすぎるので全人類に観て欲しい🦴🐉

https://youtu.be/Uuxn187guLo?si=f4iZn-S0PVPNZjvD

https://open.spotify.com/track/01yS4eW9jeCPXJgz6I7DxJ?si=XImU7ltqRd2jQb-31GSO5w&context=spotify%3Aartist%3A4YxoxjA4x3YukLHeNNgJqQ

歌詞の通り、「出会った時からのマブダチ」という関係ではないJESSEとKjが、並んでバキバキの気概全開で最高のミクスチャーロックをやっている。JESSEとKjが「お前にだけは負けるわけにいかねえ」とばかりに、彼らのバンド人生の全てぶちこんでガンガン掛け合いをかましていく曲であるため、歌詞に自身の名前や故人の名前等の固有名詞が頻出している。RIZEの歌詞でも固有名詞が多く出てくる印象はあったが、具体的な数は流石に把握していなかった。
というわけで、以前他のバンドPeople in the boxの歌詞でスクレイピングをしたことがあるため、同様の方法でJESSEの歌詞を見てみることにした。

https://qiita.com/bashildon3843/items/62aeb3445ab961b520b9

# 目的
JESSEの言葉の弾丸の構成要素をスクレイピングで調べる。
※The BONEZとJESSE個人名義の方の歌詞は基本英語なので、日本語多めのRIZEの歌詞でやる

# ①スクレイピング
```Python
# 準備
pip install --upgrade pip
pip install beautifulsoup4
pip install requests

import requests
from bs4 import BeautifulSoup

# アーティストのページURL
url = 'https://www.uta-net.com/artist/808/'

response = requests.get(url)
soup = BeautifulSoup(response.text, 'html.parser')

# 曲のリンクを格納するリスト
song_links = []

# すべての曲のリンクを取得
for link in soup.find_all('a'):
    href = link.get('href')
    if href and '/song/' in href:  # 曲へのリンクを確認
        full_link = f'https://www.uta-net.com{href}'
        song_links.append(full_link)

# 各曲の歌詞を取得
for song_link in song_links:
    song_response = requests.get(song_link)
    song_soup = BeautifulSoup(song_response.text, 'html.parser')
    
    lyrics = song_soup.find('div', id='kashi_area').text
    
lyrics_data = []

# すでに定義されているsong_linksリストを使用
for song_link in song_links:
    song_response = requests.get(song_link)
    song_soup = BeautifulSoup(song_response.text, 'html.parser')
    
    # 曲のタイトルと歌詞を取得
    title = song_soup.find('title').text
    lyrics = song_soup.find('div', id='kashi_area').text.strip()  # .strip()で前後の不要な空白を削除
    
    # 曲のタイトルと歌詞をリストに追加
    lyrics_data.append({
        'title': title,
        'lyrics': lyrics
    })
```

# ②取得データをデータフレームにする
```python
import pandas as pd

# リストをDataFrameに変換
df_lyrics = pd.DataFrame(lyrics_data)

def count_words(lyrics, word):
    return lyrics.count(word)
```
# ③固有名詞のカウント
## 地名編

```Python
# 各単語に対してカウントを行う
df_lyrics['日本_count'] = df_lyrics['lyrics'].apply(lambda x: count_words(x, '日本'))
df_lyrics['東京_count'] = df_lyrics['lyrics'].apply(lambda x: count_words(x, '東京'))
df_lyrics['江戸_count'] = df_lyrics['lyrics'].apply(lambda x: count_words(x, '江戸'))
df_lyrics['品川_count'] = df_lyrics['lyrics'].apply(lambda x: count_words(x, '品川'))
df_lyrics['五反田_count'] = df_lyrics['lyrics'].apply(lambda x: count_words(x, 'GOTANDA'))
df_lyrics['戸越_count'] = df_lyrics['lyrics'].apply(lambda x: count_words(x, '戸越'))
df_lyrics['下北_count'] = df_lyrics['lyrics'].apply(lambda x: count_words(x, '下北'))

# 各単語の総出現回数を集計
total_counts = {
    '日本': df_lyrics['日本_count'].sum(),
    '東京': df_lyrics['東京_count'].sum(),
    '江戸': df_lyrics['江戸_count'].sum(),
    '品川': df_lyrics['品川_count'].sum(),
    '五反田': df_lyrics['五反田_count'].sum(),
    '戸越': df_lyrics['戸越_count'].sum(),    
    '下北': df_lyrics['下北_count'].sum()
}

print(total_counts)
```
#### 出力結果
```Python
{'日本': 14, '東京': 5, '江戸': 11, '品川': 0, '五反田': 7, '戸越': 2, '下北': 1}
```
| 地名     | 回数 |
|----------|------|
| 日本     | 14   |
| 東京     | 5    |
| 江戸     | 11   |
| 品川     | 0    |
| 五反田   | 7    |
| 戸越     | 2    |
| 下北     | 1    |

「火事と喧嘩は江戸の華」「GOTANDA」のおかげで、江戸率と五反田率が高めだった。
JSFには品川グッズもあるので「品川」は出てくるかなと思ったのだがなかった。

https://cloudland33.com/?page=2

## メンバー編
```Python
# 各単語に対してカウントを行う
# lower()で文字列を小文字に変換して'JESSE'と'Jesse'の両方をカウント
df_lyrics['RIZE_count'] = df_lyrics['lyrics'].apply(lambda x: count_words(x, 'RIZE'))
df_lyrics['雷図_count'] = df_lyrics['lyrics'].apply(lambda x: count_words(x, '雷図'))
df_lyrics['JESSE_count'] = df_lyrics['lyrics'].apply(lambda x: count_words(x.lower(), 'jesse'))
df_lyrics['akkun_count'] = df_lyrics['lyrics'].apply(lambda x: count_words(x, 'nobuaki'))
df_lyrics['Tokie_count'] = df_lyrics['lyrics'].apply(lambda x: count_words(x.lower(), 'tokie'))
df_lyrics['Naka_count'] = df_lyrics['lyrics'].apply(lambda x: count_words(x, 'Naka'))
df_lyrics['Kenken_count'] = df_lyrics['lyrics'].apply(lambda x: count_words(x.lower(), 'kenken'))
df_lyrics['Rio_count'] = df_lyrics['lyrics'].apply(lambda x: count_words(x, 'Rio'))

# 各単語の総出現回数を集計
total_counts = {
    'RIZE': df_lyrics['RIZE_count'].sum(),
    '雷図': df_lyrics['雷図_count'].sum(),
    
    'JESSE': df_lyrics['JESSE_count'].sum(),
    'あっくん': df_lyrics['akkun_count'].sum(),
    'Tokie': df_lyrics['Tokie_count'].sum(),
    'Naka': df_lyrics['Naka_count'].sum(),
    'Kenken': df_lyrics['Kenken_count'].sum(),    
    'Rio': df_lyrics['Rio_count'].sum()
}

print(total_counts)
```
#### 出力結果
```Python
'RIZE': 86, '雷図': 10, 'JESSE': 8, 'あっくん': 5, 'Tokie': 2, 'Naka': 1, 'Kenken': 7, 'Rio': 1
```
| 名前     | 回数 |
|----------|------|
| RIZE     | 86   |
| 雷図      | 10   |
| JESSE    | 8    |
| あっくん  | 5    |
| Tokie    | 2    |
| Naka     | 1    |
| Kenken   | 7    |
| Rio      | 1    |

筆者は歌詞を読まないため、JESSEが「RIZE」と「雷図」両方を使っていることに今回初めて気付いた。
金子兄より弟の方が歌詞登場回数は多かった。kenkenの方が加入は後からなのに、そうなんだ。サポートのRioも歌詞に出てくるのもなんか嬉しい。
私がRIZEを好きになったのは「Live or Die」からなので、もっとJESSE登場頻度は高いのではないかと想定していたのだが、実際はそこまでではなかった。

# 感想
「スクレイピングしてきて特定のワードをカウントする」というのは私にとっても新規性がある手法ではないし、どうせ書くなら形態素くらいやりなよとは思うのだが、「今これをただ知りたい」という時にできる方法を自分で持っているというのは人生を楽しくするな～と思った。
QiitaもPythonもしばらくサボっていたが、やはりここいらで再開しようと思う。spacyなるライブラリを使えば、固有名詞を特定して抽出してくれるので、いずれやってみたい。

最後までお読みいただきありがとうございました⚡️

# おまけ

家宝

![IMG_4265.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3661209/aa8ca11a-a3b2-c509-3ed1-fd4b6e6db7ab.jpeg)