block.fmを!!!スクレイピング!!!!したい!!!!! (Scalaのfor式、Futureを添えて)
みなさん、block.fm聴いてますか!スクレイピングしてますか!?(普通はしません)
この記事はWanoグループアドベントカレンダーの11日目の記事です。
(12/12に書いてるけど、この業界は業務開始時間までは前日扱いだからいいよね)
前回はポエムでお茶を濁しましたが、今回はちょろっとコードが出てきます。
(スクレイピングネタは去年もやったけどね)
block.fmってなにさ
block.fm(ブロックエフエム)は日本のインターネットラジオ局。音楽プロデューサーでm-floのメンバーでもある☆Taku Takahashiが主宰し、エレクトロサウンドを中心に多岐に渡るジャンルをオンエアしている。2008年に「TCY Radio Tokyo」としてスタートし、2011年11月11日午後11時11分にblock.fmと名前を変えて装いをあらたにした。レコード会社からの影響を排除した運営で音楽性を追求した編成を心掛けている。
wikipediaより引用
まあ早い話が、ダンスミュージック主体のインターネットラジオ局です。
ちなみに私はRadio REBOOTとLocalizeのリスナーです。
なぜblock.fmをスクレイピングしたいのか
block.fmは生放送と、最新回のアーカイブ配信とで構成されるんですが、アーカイブ配信は最新回のみで過去のものは視聴できないんですね。番組自体はいいんですが、番組中で放送された楽曲の一覧であるトラックリストを参照したいわけです。(音楽配信サイトで検索するから)
で、トラックリストだけでいいからjsonとかxmlで保存できないかと思ったのが事の発端というわけです。
スクレイピング可能なのか
SPA(Riot.jsっぽい)として動いてるので、ブラウザ使わないと無理ぽw
しかたないので、chrome-dev-toolsとにらめっこして、チャンネル一覧とトラックリストのAPIを特定しました。
Scalaでやる必要あるのか
ないよ!
多分今回はLLでやるほうが楽
実装
httpclientにいろんなhttpclientのラッパーであるsttp、jsonパーサにcirceを使いました。
これ、Rubyとかでハッシュマップにデコードしたらすごい短くなると思うんですけど、なんか長くなってしまいましたね。
circeの標準デコーダにSeq[Map[String, Any]]が存在せず、かといって一発ネタのためにcase class作ってデコードするのもなーと横着してたらこんなコードになってしまいました。
for式を使ってるので、EitherとかOptionの結果取り出しはスマートに書けてるんですが、結局APIは逐次発行してるので、Future使う旨味は無いですねこのサンプルだと。
番組IDを使って複数のAPIに同時にアクセスして結果を待ち合わせする場合なんかはFutureがうまい具合に使えるんですけどね。
まとめ
Scalaのfor式、Option、Either、Futureの旨味を知りたい人はこんなブログ見てちゃダメ。
気になる人はそのまんま「Scala for式 Option Either Future」とかでググってみましょう。
他所様をむやみにスクレイピングすんのもダメ。
参考
sttp: the Scala HTTP client you always wanted! — sttp 1.0 documentation