読者です 読者をやめる 読者になる 読者になる

【スクレイピング】ONE OK ROCKの曲の英単語は何が1番多いのかをスクレイピングによって明らかにした話

スクレイピング歴もクソもないまま単に興味でWebスクレイピングをやってみた。

f:id:n-kyoncy:20170506073250j:plain ※ 何も関係ありません。気が狂っただけです。

今回のテーマはちょっと個人的に面白みのあるものとタイトルにも示した通りです。 『人気の曲ランキング20000曲の中で使われている計7文字以上のフレーズTOP10』 『ONE OK ROCKの全曲の中で使われている英単語TOP10

python3 で全部やってます。さっそく。

 

・人気の曲ランキング20000曲の中で使われている計7文字以上のフレーズTOP10

ソースコードは以下のようになります。 コメントが適切かはわかりませんが、記載します。

from bs4 import BeautifulSoup
from collections import Counter
import urllib.request as req
import re                                                                                       # 正規表現を使うためのライブラリ

links = []
results = []

for i in range(1, 101):
    url = "http://j-lyric.net/lyric/p{0}.html".format(i)                                        # ランキングデータがあるhtmlのURL(1~2000位)
    res = req.urlopen(url)                                                                      # URLで表されるネットワーク上のオブジェクトを読込み用に開く
    soup = BeautifulSoup(res, "html.parser")                                                    # htmlをパース
    refs = soup.find("div", id="rankingBlock").find_all("a", class_="title")                    # idがrankingBlock内のclassがtitleのものを取得

    for ref in refs:
        links.append("http://j-lyric.net" + ref.attrs["href"])                                  # ランキングページには20個のランキングデータがあるのでそれぞれのURLを取得
    
    print("{0} is done.".format(i))                                                             # ページごとの進捗を表示

for link in links:
    url2 = link                                                                                 # limksの中のURL
    res2 = req.urlopen(url2)                                                                    # URLで表されるネットワーク上のオブジェクトを読込み用に開く
    soup2 = BeautifulSoup(res2, "html.parser")                                                  # htmlをパース
    lyrics = str(soup2.find("p", id="lyricBody"))                                               # idがlyricbodyのデータを取得
    lyrics = lyrics.replace("\n", "").replace("\r", "").replace("\u3000", "")                   # 改行やラインフィード,全角スペースを削除

    print(lyrics)

    pattern = r"<.*?>"                                                                          # < と >の間の文字抽出 . は改行以外の任意の1文字にマッチ,*? は直前の文字が0個以上連続したものにマッチするが可能な限り短い範囲
    lines = re.split(pattern, lyrics)                                                           # lyricsをpatternがあるたびに分割してlinesに格納

    print(lines)

    group = []

    for line in lines:
        engline = ""
        for c in line:
            if ord(c) < 128:                                                                    # その文字のUnicodeコードポイントを表す整数を返す.128以下なら通る(英単語を見るから)
                engline += c                                                                    # engineに格納していく
        engline = engline.replace("(", "").replace(")", "").replace(":", "").replace("!", "")   # 余計な文字を消す
        engline = engline.strip()                                                               # 分割する
        engline = engline.lower()                                                               # 小文字に変換する
        if not len(engline) < 7:
            group.append(engline)                                                               # 長さが7以上ならgroupに格納
    group_uniq = list(set(group))                                                               # リストから重複した要素を取り除き,ユニークな要素だけを持つリストを得る

    for element in group_uniq:
        results.append(element)                                                                 # ユニークな要素を持つリストの要素をresultsに格納
    print("{0} is done.".format(url2))                                                          # ランキングのデータごとの進捗を表示

counter = Counter(results)                                                                      # Countする(クソ便利)
text_write = open('fav_word.txt', 'w')                                                          # データ書き込み用のファイルオープン

for lin, cnt in counter.most_common(10):                                                        # 10個の最頻ワードを取り出す
    print("{0} ({1})".format(lin, cnt))                                                         # データと数を出力
    text_write.write("{0} ({1})".format(lin, cnt))                                              # ファイルに書き込み
    text_write.write("\n")
text_write.close()

実行結果

i love you (186)
oh yeah (134)
everyday (89)
tonight (67)
let's go (67)
love song (64)
wow wow (64)
yeah yeah (63)
everybody (62)
my heart (58)

邦楽には,i love you が多いのか、邦楽は恋愛とパリピ指向なのかな。 wow wowとかoh yeahとか西野カナが使ってそう。 love song ってフレーズがランクインしてるのが面白いな。

 

ONE OK ROCKの全曲の中で使われている英単語TOP10

ちょこっといじっただけ
4文字以上だとthis thatとかで埋め尽くされるから5文字以上という制約
divタグに囲まれたaタグの中にhref情報があったて、どう抽出したらいいかわからんかったから
とりあえず曲のリストの部分だけ取り出して、

refs = refs_.find_all(href=re.compile("/artist/a04cc4b/"))

で抽出した。

from bs4 import BeautifulSoup
from collections import Counter
import urllib.request as req
import re                                                                                       

links = []
results = []

url = "http://j-lyric.net/artist/a04cc4b/"                                       
res = req.urlopen(url)                                                              
soup = BeautifulSoup(res, "html.parser") 
refs_ = soup.find("div", id="lyricList")
refs = refs_.find_all(href=re.compile("/artist/a04cc4b/"))

for ref in refs:
    links.append("http://j-lyric.net" + ref.attrs["href"])

for link in links:
    url2 = link                                                                                 
    res2 = req.urlopen(url2)                                                    
    soup2 = BeautifulSoup(res2, "html.parser")                                                   
    lyrics = str(soup2.find("p", id="lyricBody"))                                           
    lyrics = lyrics.replace("\n", "").replace("\r", "").replace("\u3000", "")  

    pattern = r"<.*?>"                                                                 
    lines = re.split(pattern, lyrics)                                   

    group = []

    for line in lines:
        words = line.split()
        for word in words:
            engline = ""
            for c in word:
                if ord(c) < 128:                                                       
                    engline += c                                                            
            engline = engline.replace("(", "").replace(")", "").replace(":", "").replace("!", "")
            engline = engline.strip()                                           
            engline = engline.lower()                                           
            if not len(engline) < 5:
                group.append(engline)                                                           

    for element in group:
        results.append(element)                                                     
    print("{0} is done.".format(url2))                                                         

counter = Counter(results)                                                                      
text_write = open('oneok_word.txt', 'w')                                                           

for lin, cnt in counter.most_common(20):                                                       
    print("{0} ({1})".format(lin, cnt))    
    text_write.write("{0} ({1})".format(lin, cnt))
    text_write.write("\n")
text_write.close()

実行結果

don't (130)
never (90)
you're (78)
can't (76)
right (56)
gonna (54)
always (53)
nothing (51)
going (42)
let's (41)
everything (39)
wanna (39)
there (36)
something (32)
'cause (32)
tonight (32)
that's (31)
what's (30)
think (27)
won't (27)

don’tが多いですね。でもワンオクの特徴的なのワードでんな。
4文字の方が良かったかな、まぁええや
短縮形ちゃんと使ってんだな笑 8文字での結果もやった

everything (39)
something (32)
standing (26)
everybody (21)
wherever (19)
whatever (13)
yourself (12)
heartache? (12)
anything (11)
nobody's (11)
screaming (9)
brighter (8)
somebody (8)
together (8)
grenades (8)
everyone (7)
suddenly (7)
thinking (6)
breaking (6)
understand (5)

曲名にある単語やったりするからワンオクっぽい。以上。

今度はデータベース使ったりして機械学習方面に寄せていってみたい。あと逐次実行してデータ収集的なことしてみたい。