【Scraping】日本一素晴らしいクリスマスソングの歌詞を作る


突然ですが、ピチカート・ファイブの「12月24日」というクリスマス・ソングがとても好きです。なんといっても歌詞が良い。

>東京はいつだって
>いつだってにぎやかだけど
>12月24日
>ひとりきりは少し寂しい

あの明るい曲調に、切ない歌詞がのるというのがたまらないですね！今の僕の心情にぴったり寄り添ってきます。こんな素晴らしい歌詞が書けたらなあと憧れた諸兄姉も多いのではないかと思います。
どうもクリスマスというシーズンには、人をそわそわさせるワードがつきもののようです。
そこで閃いたのですが、クリスマス・ソングの中でも名曲と言われる曲たちの歌詞を組み合わせれば、それはもう素晴らしい歌詞が出来上がるのではないでしょうか？

というわけで、「実行するだけでクリスマス・ソングの名曲の歌詞を組み合わせて表示してくれるプログラム」を作ってみました。ご査収ください。

```ruby:lyric_maker.rb
require 'mechanize'

class XmasLylicMaker < Mechanize

  SONGS_URL = "http://jpop.ninpou.jp/field/qurisumas.html"
  LYRICS_URL = "http://www.uta-net.com/"
  NARROW_BY_SONG = 2

  def initialize
    super
  end

  def remix_lylics
    lyrics = songs_list.map do |song|
      result_page(song).search('.td5').map { |list| list.text } if result_page(song)
    end
    puts lyrics.flatten.uniq.shuffle!.shift(13)
  end

  private

  def songs_page
    get(SONGS_URL)
  end

  def search_page
    get(LYRICS_URL)
  end

  def result_page(song_name)
    begin
      search_page.form_with(id: 'search_form') do |form|
        form.Keyword = song_name
        form.field_with(name: "Aselect").value = NARROW_BY_SONG
      end.submit
    rescue
    end
  end

  def songs_list
    songs_page.search('h3').map do |song_name|
      text = song_name.text
      text.slice!(0)
      text
    end
  end

end

XmasLylicMaker.new.remix_lylics
```

こちらを実行するだけで、ターミナル上に歌詞がいい感じに並びます。気になる結果は後程紹介するとして、まずは簡単にコードの解説をします。

大まかな流れは、「クリスマスの名曲ランキングが載っているページから曲名を取得→取得した曲の歌詞を取得、ランダムに並び替える」というものになります。

まずはこの辺りまで。


```ruby:lyric_maker.rb
require 'mechanize'

class XmasLylicMaker < Mechanize
```

今回はScrapingによってあるページから情報を拝借してくるので、gem `mechanize`を利用します。
また、`class XmasLyricMaker`は「クリスマス・ソングの歌詞を作る」というクラスなので、Mechanizeのメソッドを利用してHTMLを読み込まなければいけません。そこで、`Mechanize`クラスを継承させています。

続きまして`initialize`メソッド付近まで。

```ruby:lyric_maker.rb
  SONGS_URL = "http://jpop.ninpou.jp/field/qurisumas.html"
  LYRICS_URL = "http://www.uta-net.com/"
  NARROW_BY_SONG = 2

  def initialize
    super
  end
```

今回は定数でScrapingに行くURLなどを定義しています。実際に遷移してみていただければわかりますが、それぞれクリスマスの名曲特集のページと、歌詞検索サービスサイトのトップページのURLとなっています。
`initialize`メソッドですが、継承元の`Mechanize`のinitializeを受け継ぐために`super`を記述しています。

続いてはファイル中で唯一クラス外から呼び出されている`remix_lyrics`メソッドです。

```ruby:lyric_maker.rb
  def remix_lylics
    lyrics = songs_list.map do |song|
      result_page(song).search('.td5').map { |list| list.text } if result_page(song)
    end
    puts lyrics.flatten.uniq.shuffle!.shift(13)
  end
```

`songs_list`の前には`self.`が省略されています。つまりこちらはインスタンスメソッドであり、`remix_lyrics`メソッドのレシーバである`XmasLyricMaker`クラスのインスタンスがこのメソッドを呼び出している、ということになりますね。`songs_list`メソッドを見てみましょう。

```ruby:lyric_maker.rb
  def songs_list
    songs_page.search('h3').map do |song_name|
      text = song_name.text
      text.slice!(0)
      text
    end
  end
```

この中に書かれている`songs_page`もメソッドの呼び出しです。呼び出しているのは同様にレシーバのインスタンスになります。`songs_page`メソッドはこちらです。

```ruby:lyric_maker.rb
  def songs_page
    get(SONGS_URL)
  end
```

このメソッドにより、ScrapingしたいページのHTML情報を取得してきています。
`songs_list`メソッドの返り値は、`["曲名", "曲名", "曲名"]`といったクリスマスの名曲のタイトルが入った配列にになります。

続いて、`result_page`メソッドです。

```ruby:lyric_maker.rb
  def result_page(song_name)
    begin
      search_page.form_with(id: 'search_form') do |form|
        form.Keyword = song_name
        form.field_with(name: "Aselect").value = NARROW_BY_SONG
      end.submit
    rescue
    end
  end
```

こちらは、引数として受け取った曲名を歌詞検索サービスサイトの検索フォームに入力し、そのタイトルを含む曲一覧のページの情報を返します(`Winter, again`が上手く検索出来ずにエラーになるのでやむなく例外処理で回避、なぜだTERUよ)。

取得した曲一覧ページの`.td5`というclassのついた要素に、お目当ての歌詞があります。あとはそれを`text`メソッドで文字列として取り出し、文字列の入った配列として返していくだけです。すると、変数`lyrics`は二重配列となります。

```ruby:lyric_maker.rb
  def remix_lylics
    lyrics = songs_list.map do |song|
      result_page(song).search('.td5').map { |list| list.text } if result_page(song)
    end
    puts lyrics.flatten.uniq.shuffle!.shift(13)
  end
```

最後は、`flatten`して`uniq`して`shuffle!`した配列を出力すれば、目的を達成できるという寸法です。行数は、1番の歌詞を数えたらだいたいそれくらいのものが多かったので13行にしています。つまり適当です。

色々気に入らないところもありますが、ひとまず動いてるのでいったん良しとしましょう。

(24日になったら最新版のRubyを入れて、`try`メソッドなど試してみたいものです)

それではお待たせしました、本エントリーの成果である「日本一凄いクリスマスソングの歌詞」を公開します。

>君の隣でなら深く大きく深呼吸
磨り減った靴でまだ見ぬ明日へ
センチメンタルと祝福の気持ち
No pain心がすれ違う時にも
I BELIEVEほら今自分信じて
うまくいかないno good day
I Believe大事なことは
壊れかけた宝物を両手に抱えて
waiting all my life for girl
何処に行けば辿り着くの
I Believeさよならじゃない
Setting along the scenery
White Silent Night

どうですかこの素晴らしい歌詞は。ミリオンヒット間違いなしです。秋◯康が悔しがる姿が目に浮かびます。
特に、サビらしき部分で「I BELIEVE ~」「I Believe ~」ときちんと韻を踏んでいることにポテンシャルを感じますね。大文字と小文字にどんな意味の違いが込められているのでしょうか。そしてクリスマスという言葉が一度も出てきません。
他にも色々と面白い発見がありましたが、これ以上はお目汚しとなるので控えておきます。

工夫すれば、様々な「日本一凄い」歌詞が作れそうですね。

皆さんも是非一度お試しあれ！

※なお、このプログラムを用いて実際に楽曲を作ることは当然のごとく著作権に違反します。やめておきましょう。

当局からは以上になります。お読みいただき、ありがとうございましたm(_ _)m