こんにちは、eQOL(イーキュオル)の山下です。
私事で恐縮ですが、家族でMr.Childrenのファンです。youTubeのイントロクイズに飽き足らず、末っ子の次女が中間イントロ(中間でもイントロというのか?)クイズアプリを作ってくれました。ファン歴が最も長い私ですが、子供達に完敗。「歌詞から曲名を当てるゲームだったら勝てる」と宣言し、このアプリを作りました。宣言通り、このゲームで私は家長としての威厳を取り戻しましたが、それ以上にゲームとしても結構面白い。もし貴方が(真の?)ミスチルファンでしたら楽しめること間違いなしです。無料で使えるwebアプリとして公開していますので、ぜひ一度試してみてください。

アプリの制作過程と構成を簡単に紹介します。
歌詞データの取得
歌ネットというサイトで様々なアーティスト楽曲の歌詞を調べることができます。Pythonのスクレイピング機能を使ってミスチル全曲の歌詞を取得します。2023/11/5現在で258曲が登録されていました。Google Colaboratoryを使用しています。
import requests
from bs4 import BeautifulSoup #スクレイピング用ライブラリ
import pandas as pd #データを格納するライブラリ
import time
import re
from datetime import datetime
list_df = pd.DataFrame(columns=['アーティスト', '曲名', '作詞', '作曲', '歌詞'])
base_url = 'https://www.uta-net.com'
user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36'
header = {'User-Agent': user_agent} #このヘッダーがないとアクセスできません。
for page in range(1,3):
url = 'https://www.uta-net.com/artist/684/0/' + str(page) + '/' #アーティスト番号が684
response = requests.get(url, headers=header)
soup = BeautifulSoup(response.text, 'lxml')
links = soup.find_all('td', class_='sp-w-100 pt-0 pt-lg-2') #この辺りはhtmlファイルを確認しながら
for link in links:
song_url = base_url + link.a.get('href')
response = requests.get(song_url, headers=header)
soup2 = BeautifulSoup(response.text, 'lxml')
song_name = soup2.find('h2', class_="ms-2 ms-md-3")
song_name = song_name.getText()
artist = soup2.find('span', itemprop='byArtist name')
artist = artist.getText()
song_metadata = soup2.find('p', class_="ms-2 ms-md-3 detail mb-0")
song_metadata = song_metadata.getText().replace(' ', '').split()
lyricist = song_metadata[0].split(':')[1]
composer = song_metadata[1].split(':')[1]
song_lyric = soup2.find('div', id='kashi_area')
song_lyric = list(song_lyric.children)
modified_lyric = [str(i).replace('<br/>', '\n') for i in song_lyric]
modified_lyric = ''.join(modified_lyric)
tmp_se = pd.DataFrame([[artist], [song_name], [lyricist], [composer], [modified_lyric]], index=list_df.columns).T
list_df = list_df.append(tmp_se)
time.sleep(0.3)
#最後にpandasデータをcsvファイルとして保存します。
list_df.to_csv("/content/drive/My Drive/lyrics/MrChildren_lyrics.csv", index=False)
歌詞データをFirestoreに登録
今回はReactを使ってアプリを作ったので、Reactで扱いやすいデータベースとしてGoogleのFirestoreを選択しました。csvデータをFirestoreに登録するには様々な方法がありますが、以下はGoogle Apps Scriptを使ってSpreadsheetからFirestoreにデータ保存する方法です。Firestoreの設定やSpreadsheet側の設定については以下のサイトなどが参考になります。
GAS:Google App Scriptsを使ってSpreadSheetに登録したデータをFirestoreにインポートする
Reactアプリを作成
Reactアプリの作成に関しては数多くの情報がありますので一般的なことは割愛して、少し工夫したところだけ紹介します。歌詞のデータはフレーズごとに改行コードを含むテキストデータですが、ここから1行ランダムに抜き出した上で、最大文字数10文字以下となるようにその行からランダムな場所を抜き出して問題文として出題します(行の先頭からだけでなく途中からになることがあるので難易度が一気にまします)。解答ボタンを押すと、歌詞全文を表示するとともに、出題のフレーズを青字で表示されるようにしたいと思いましたが、長いテキスト文の一部を(動的に)色を変えて表示するというのに意外と手こずってしまいました。結果たどり着いた解決策は、1.歌詞全文を改行コードで区切ってフレーズごとの文字列リストし、2.出題した行だけ青文字のスタイルを当てたReact.Fragmentのリストに変換して、これを表示させるということでした。
const showLyric = (lyric, n) => {
let l = lyric;
const l2 = l.split('\n').map((item, index) => {
if (index === n ){
return (
<React.Fragment><div className="textBlue">{item}<br/></div></React.Fragment>
);
} else {
return (
<React.Fragment><div>{item}<br/></div></React.Fragment>
);
}
})
setLyric(l2);
}
次女も通学時に遊んでくれています。ミスチル以外のアーティストでやってみたいという方がいたら、協力しますよ。


