またRとニコニコ動画ネタ。様々なデータを取得しやすいのでRの勉強するには、ニコニコ動画のデータを使うのはよさそうです(ただたんに、よく利用しているサイトということもありますが)。
まず、ニコニコ動画には、動画情報を取得できるAPIがあります。
参考:ニコニコ動画APIとは (ニコニコドウガエーピーアイとは) [単語記事] – ニコニコ大百科
また、RにはXMLを解析する『XML』という名前そのままなパッケージがあります。
参考:XMLデータの扱い方
今回はそれらを利用してRでニコニコ動画のAPIを取得してみます。
まずは、RでXMLのパッケージのインストール
> install.packages("XML") Installing package into ‘C:/Users/*****/Documents/R/win-library/3.0’ (as ‘lib’ is unspecified) trying URL 'http://essrc.hyogo-u.ac.jp/cran/bin/windows/contrib/3.0/XML_3.98-1.1.zip' Content type 'application/zip' length 4288136 bytes (4.1 Mb) opened URL downloaded 4.1 Mb package ‘XML’ successfully unpacked and MD5 sums checked The downloaded binary packages are in C:\Users\*****\AppData\Local\Temp\Rtmpu2nDdW\downloaded_packages > library(XML)
こんな感じになったら、とりあえずparseXMLを使ってニコニコ動画APIを取得。今回は定番のsm9(新・豪血寺一族 -煩悩解放 – レッツゴー!陰陽師)を使用
> nico <- xmlToDataFrame("http://ext.nicovideo.jp/api/getthumbinfo/sm9") > nico video_id title 1 sm9 新・豪血寺一族 -煩悩解放 - レッツゴー!陰陽師 description 1 レッツゴー!陰陽師(フルコーラスバージョン) thumbnail_url 1 http://tn-skr2.smilevideo.jp/smile?i=9 first_retrieve length movie_type size_high 1 2007-03-06T00:33:00+09:00 5:19 flv 21138631 size_low view_counter comment_num mylist_counter 1 17436492 13653718 4160683 134524 last_res_body 1 ヤバい倒れる陰陽師 腹ペコだお陰陽師 藤木ルナ! うううううううううう watch_url thumb_type embeddable 1 http://www.nicovideo.jp/watch/sm9 video 1 no_live_play 1 0 tags 1 陰陽師レッツゴー!陰陽師公式音楽ゲーム新・豪血寺一族sm9すべての元凶最古の動画運営長の中の人 user_id 1 4 > nico['video_id'] video_id 1 sm9 > nico['tags'] tags 1 陰陽師レッツゴー!陰陽師公式音楽ゲーム新・豪血寺一族sm9すべての元凶最古の動画運営長の中の人
分かりにくいですが、どうも取得できたみたいです。タグが連結されてしまってますが、他は問題なさそう。
ところで、ニコニコ動画のAPIの動画情報は動画一つ一つでしか取得できないようです。でも、2つ以上の動画情報をデータフレームにしたいということもあるので、その方法を考えてみました。
まずは、取得した動画IDの取得。今回は、カテゴリ合算の総合ランキングの合計ランキングにあるトップ100の動画の情報を取得してみることに。
まずはその習得手順。ウェブ開発者ツールを開いて、コンソール画面を開き、以下のスクリプトを実行。
var txtVideoInfo = "videoID,adsPoint\n"; $('.videoRanking:lt(100)').each(function(i){ var linkTxt = $(this).find('.itemTitle a').attr('href'); var videoID = linkTxt.replace(/^.*watch\/([a-z][a-z]\d+).*/ ,"$1"); var ads = $(this).find('.ads a').html().replace(/,/g ,""); if(i==99){ txtVideoInfo += videoID + "," + ads; }else{ txtVideoInfo += videoID + "," + ads + "\n"; } }); $('header.header').append($('<textarea />').val(txtVideoInfo));
そうすると、メニューバーの下に動画IDと宣伝ポイントがカンマ区切りで書かれたテキストエリアが表示されると思うので、それを全て選択してコピーします(ChromeやFirebugを使っている場合は、12行目を『copy(txtVideoInfo);』してもOK)。なんだかムダなことをやっていると思われるかもしれませんが、AutoPage系の拡張機能や、先日紹介したGETパラメータを削除するユーザースクリプト(ニコニコ動画のGETパラメータ付きリンクを取り除くユーザースクリプト書いた | while(isプログラマ))を使ってる場合を考慮して書いています。if文は必要なさそうだったのですが、copyメソッドを使う場合は最後に空白行を追加してしまうという問題があったため、if文で最後の行だけ”\n”を追加しないようにしています。ニコニ広告のポイント数は必要ありませんが、後でつかおうと思ったため取得しました。
とりあえず、上記で取得したテキストをRに取り込み。
> nico.table <- read.csv("clipboard", header=TRUE) > head(nico.table) videoID adsPoint 1 sm13848574 139805800 2 sm8628149 2402200 3 sm9 389000 4 sm2057168 259300 5 sm1097445 209600 6 sm1715919 46800
うまく取得できてるよう。
というわけで早速、この取得した動画IDのAPIを取得して、結合したデータフレームを作ってみたいと思います。
> nico.frame <- data.frame() > for(i in 1:100){ + apiTxt <- paste("http://ext.nicovideo.jp/api/getthumbinfo/", nico.table[i,1], sep="") + nico.frame <- rbind(nico.frame, xmlToDataFrame(apiTxt)[-19]) + }
4行目の[-19]というのは、19列目を除くという意味です。公式動画だと19番目のuser_idがないことがあるそうなので、19番目をはぶくことにしました。
これでうまくいくはず(API自体をうまく取得できなかった場合や、削除となっている動画用のXMLが取得されてしまった場合の対処はしてません)。
そしてこれを、
> write.table(nico.frame, "nicoFrame.txt", quote=F, row.names=F, append=F, sep="\t")
として、得たテキストファイルが以下。
nicoFrame
うまく取得できてるようです。
ところで、APIの動画情報にはニコニ広告のポイントは書いてありません。ニコニ広告自体が途中からでてきたサービスだからなのかもしれませんが、とりあえず今回はニコニ広告のポイントをすでに取得してあるので、それを結合してみることに。今回は動画ID,タイトル,再生数,コメント数,マイリスト数,ニコニ広告ポイント数のみのデータフレームを作成することに。
> nico.frame2 <- data.frame(video_id=nico.frame$video_id, title=nico.frame$title, view_counter=nico.frame$view_counter, comment_num=nico.frame$comment_num, mylist_counter=nico.frame$mylist_counter, adsPoint=nico.table$adsPoint) > write.table(nico.frame2, "nicoFrame2.txt", quote=F, row.names=F, append=F, sep="\t")
できたファイル:nicoFrame2
これもうまくいきました。
ところで、今回ニコニ広告のポイント数をブラウザからとることができましたが、普通にソースをとってきてもわからないよう。どうも、ソースを読み込んだ後にJavaScriptでニコニ広告のポイント表示をしているようなのですが、調べてみてもその仕組みが分からず(ranking.jsというファイルで何かやってそうなのですが・・・)。
最後に、動画がない場合の対策。動画がない(例えば、sm1)が含まれている可能性がある場合は、ncolで列数を調べ、18の場合のみデータフレームに追加するという作業を行うといいかもしれないです。
試しに、sm1~sm100の動画情報を取得した場合は以下のように。
> nico.frame3 <- data.frame() > for(i in 1:100){ + apiTxt <- paste("http://ext.nicovideo.jp/api/getthumbinfo/sm", i, sep="") + nico.xml <- xmlToDataFrame(apiTxt)[-19] + if(ncol(nico.xml) == 18){ + nico.frame3 <- rbind(nico.frame3, xmlToDataFrame(apiTxt)[-19]) + } + } > nico.frame3$video_id [1] sm9 sm13 sm14 sm16 sm31 sm41 sm42 sm43 sm46 sm50 sm53 [12] sm56 sm57 sm60 sm69 sm70 sm76 sm79 sm83 sm84 sm94 sm98 [23] sm99 23 Levels: sm9 sm13 sm14 sm16 sm31 sm41 sm42 sm43 ... sm99
sm1~sm100までは23の動画が残っているということがわかります。
タグがうまく取得できない問題は今後の課題に(これができなきゃカテゴリーすら分からない)。XMLライブラリをもう少し勉強すれば分かるような気はするのですが・・・。
ニコニ広告の自動取得は難しそう。ニコニ広告の動画ページ(sm9の場合)のソースを見れば分かるには分かるのですが・・・。
コメント