last.fm APIをためしてみた

自分の好みにあう新しい音楽だったりアーティストというのはいつも知りたいと思っていて、
でもいつの頃からもうあんまり情報についていけていけなくなる。


それは多分情熱みたいなのがなくなるんだろうなーと思う。


last.fmとかpandoraとかできた時は
「あーこれからはもっと知らない音楽にあほみたく出会える時代なんだ」
とか思って、実際出会ったこともあるけど、なんかそっちの偶発的な出会いを
促進しますよー的な動きは思ったほどあんまりしてないなーと思う。


で、last.fm APIをはじめて使ってみた。


last.fmではneighboursという概念であなたと似たような曲を聴いている人がいますよ、
というのがあって、
http://ws.audioscrobbler.com/1.0/user/#{USER_NAME}/neighbours.xml
APIを提供している。


人数についてはよく分からないけど、51人のneighbourが引っ張ってこれたので、
neighbourの3ヶ月以内のtop_artist - (自分のtop_artist + 自分のtop_tracks_artist)
をしてみた。


ただ、全部ひっぱるとあほみたく重いので、
neighbourは20人とか適当に指定している。
(それでもすごい重いけど)


やっぱり自分の知っているartistが多くて、
でもtop_artistは50しか出してくれない。
iTunes Library.xmlを直接読み込んで
neighbourの3ヶ月以内のtop_artist - 自分のiTunesのartist
にすればいいや、と思って試したら10.2MBのiTunes Library.xmlのあまりの重さに
めんどくさくなって断念。


それでも思ったより、全然知らないartistが多くて、
これをrailsでちょこちょこやってyoutubeとか
wikipediaへの参照とかつけたら思ったよりも使いやすかった。
もうちょっと工夫してみよう。


というか、last.fmとかこういうことをやってくれて
教えてくれたらすごいうれしいのになー。
先週のあなたと音楽の好みが似た人が聴いている、あなたが聴いたことのない[artist|曲]です、みたいな。

class Lastfm

  LOOP_COUNT = 20
  USER_NAME = 'bannyan'

  require 'rubygems'
  require 'hpricot'
  require 'open-uri'
  require 'kconv'

  def generate

    doc = Hpricot( open("http://ws.audioscrobbler.com/1.0/user/#{USER_NAME}/neighbours.xml").read.toutf8 )

    neighbours = []
    neightbour_top_artists = []

    (doc/"user").each_with_index do | name, i |
      neighbours << name.attributes['username'] if i <= LOOP_COUNT
    end

    neighbours.each do | neighbour |
      #doc = Hpricot( open("http://ws.audioscrobbler.com/1.0/user/#{neighbour}/weeklyartistchart.xml").read.toutf8 )
      doc = Hpricot( open("http://ws.audioscrobbler.com/1.0/user/#{neighbour}/topartists.xml?type=3month").read.toutf8 )
      (doc/"name").each do | name |
        neightbour_top_artists << name.inner_html.gsub(/ &amp; /, "&")
      end
    end

    doc = Hpricot( open("http://ws.audioscrobbler.com/1.0/user/#{USER_NAME}/topartists.xml").read.toutf8 )

    self_top_artists = []

    (doc/"name").each do | name |
      self_top_artists << name.inner_html.gsub(/ &amp; /, "&")
    end

    doc = Hpricot( open("http://ws.audioscrobbler.com/1.0/user/#{USER_NAME}/toptracks.xml").read.toutf8 )

    self_top_tracks_artists = []

    (doc/"artist").each do | name |
      self_top_tracks_artists << name.inner_html.gsub(/ &amp; /, "&")
    end

    uniq_artists = neightbour_top_artists - (self_top_artists | self_top_tracks_artists)

    count = Hash.new(0)
    sorted_artists = []

    uniq_artists.each{ | elem |
      count[elem] += 1
    }

    count.to_a.sort{ | key, value |
      (value[1] <=> key[1]) * 2 + (key[0] <=> value[0])}.each do | sorted_count |
      sorted_artists << sorted_count
    end

    sorted_artists.each do | artist |
      puts artist
    end

  end
end

lastfm = Lastfm.new
lastfm.generate

出力の一部

Sufjan Stevens
8
The Kooks
8
Alicia Keys
7
Amos Lee
7
Amy Winehouse
7
Arctic Monkeys
7
Belle and Sebastian
7
Ben Kweller
7
Ben Lee
7
Colbie Caillat
7
Counting Crows
7
G. Love
7
Gavin DeGraw
7
Guster
7
Ingrid Michaelson
7
James Blunt
7
Maroon 5
7
Mason Jennings
7
The Shins
7
A Fine Frenzy
6
Animal Liberation Orchestra
6

Web Services - Audioscrobbler
http://www.audioscrobbler.net/data/webservices/

Audioscrobbler Realtime Submission Protocol v1.2
http://www.audioscrobbler.net/development/protocol/