2007年9月アーカイブ
FirefoxのプラグインAdblockはオンラインDBと連携して広告をカットしてくれるそうな。
ネット広告業界に衝撃走る「Adblock」の脅威
僕は広告には意識してアンテナ張っているのでこの手のプラグインを
使うつもりはないのですが、ユーザ視点に立って見れば便利な世の中になったものです。
HDレコーダーのCMカット機能なども同じですが、
この問題は広告業界にとっては確かに脅威なのかもしれません。
でも本来広告というのはコミュニケーションなので、
不快に感じたらそく断つことができるべきものです。
広告は価値同士のマッチングにすぎません。
メディアは、消費者に対してサービスを提供する代わりに
その対価として広告を見られているわけではないのです。
広告は(多数派の)消費者にとって価値あるべきものです。
価値があれば(多数派は)カットしたがりません。
「広告カット」問題は、広告とはどうあるべきか、
ということを考えさせる良い機会になると思います。
そして収益モデルとしても、商品やサービスなどの価値の提供
すなわち企業としての支出と、それを支えるための広告主からの収入を
別々に考える単純な広告モデルが成り立ちにくくなっていることを表しています。
これはビジネスというゲームをより面白くする傾向だと思います。
いかにも学校で使いそうな教科書っぽい本でした。
いまいち経営学には興味が持てないんですけど、
戦略論とかは面白そうだったんで読んでみました。
ソフトウェア工学なんかもそうなんだけど
なんかやわらかいはずの話を無理にかためて
ありがたい教え的に装っている気がするんですね。
専門用語をたくさん定義することで
コミュニケーションしやすくなるのはわかるんだけど。
仕事全般を見てもそうだな、こう、あえてプロの壁をこしらえて
にわかは寄ってくるなよみたいな雰囲気を醸し出させている。
そうやってできた分業体制に疑問を抱かずにはいられないんです。
自分らの居場所を確保することに必死になってるんじゃないの。
まぁ自尊心が高まるのは悪いことじゃないけど、
会社がなきゃ生きていけない人間が量産されてるわけだ。
出世するのに何が一番大事だと思う?
たぶん社内営業だろうね。
いやそういうのも大事だと思うけどさぁ、
そこを頑張る時間とエネルギーを使えば、
無理矢理な分業体制を打破できるくらいの能力は十分修得可能なんじゃないか。
もちろんそんな能力は既存の会社組織には宝の持ち腐れでしかない。
と本の内容からずれすぎた。
印象に残ったキーワードをひとつ挙げるなら、「STP」
どうしてもエステーピーと発音してしまうけどたぶん、ティーと読むんだろうな。
S=Segmentation、T=Targeting、P=Positioning
セグメンテーションしてからターゲティングしてポジショニングする。
セグメンテーションとは、適した尺度を用いて市場を切り刻むこと。
ターゲティングとは、セグメンテーションによって切り出された
市場単位のどれを、自社商品のターゲットと置くのかを決めること。
ポジショニングとは、消費者から見て自社商品はどのように
位置付けられるべきか、逆視点で定義すること。
この流れは憶えておくと商品開発の初期段階では有効と思われます。
ウケる技術、温厚な上司の怒らせ方、などで有名な水野敬也氏の本です。
大人版ドラえもんとのび太みたいな物語構成になっています。
ある日、成功したいサラリーマンの主人公に、
ゾウの神様が現れて一日一日いろんな課題を出し教訓を説きつつ
主人公が少しだけど成長していく過程が物語になっています。
啓発書だけど、普通の小説として読んでも十分面白いです。
1. 成功するとは、特別になるということ
2. 特別であるということは、他人とは違うということ
3. 誰もが楽をしたい
4. 楽をすれば普通になる
5. 特別になりたければ、他人と違うことをする
6. つまり楽じゃないことをする
みんな成功したいのに成功していないのは、楽なことをしているから。
楽じゃなくなってまで成功したいとは思わない。
とかそんな感じのことが言いたいみたい。
僕も概ね同意です。
結局行き着くところは
ハイリスクハイリターン、ローリスクローリターンだよねぇとか思う。
この前作ったライブラリにクラスを追加して、
ニコニコ動画の「注目のタグ」一覧も毎日取ってみています。
上位は全然変わらないみたいだけどね。
これです→http://www.nicovideo.jp/tag
もうちょっと人にやさしく配置してくれるとうれしいのですが・・・
スクレイパー的にはありがたいんだけどw
Rubyスクリプトは下記になります。
nico.rbがライブラリで、tag.rbがクライアントプログラムです。
# nico.rb
require 'net/https'
require 'kconv'
require 'rubygems'
require 'hpricot'
module Nico
class Tags
def read (sid)
@tags = []
Net::HTTP.start("www.nicovideo.jp", 80) do |http|
response = http.get(
"/tag",
"Cookie" => "user_session=user_session#{sid}")
doc = Hpricot(response.body.tosjis)
doc.search("a/nobr").each do |e|
@tags << e.inner_text
end
end # start
end # def
def save (fname)
File.open(fname, "w") do |file|
@tags.each {|e| file.puts e }
end # open
end # def
end
def self.get_sid (mail, password)
sid = nil
https = Net::HTTP.new("secure.nicovideo.jp", 443)
https.use_ssl = true
https.start do |w|
data = "next_url=&mail=#{mail}&password=#{password}"
response = w.post("/secure/login?site=niconico", data, "Content-Length" => "#{data.length}")
sid = $1 if response["Set-Cookie"] =~ /user_session=user_session([0-9_]+)/
end
sid
end
end # module
#! ruby -Ks
# tag.rb
# ライブラリロード
require 'date'
require 'nico'
today = Date.today.strftime("%Y%m%d")
sid = Nico::get_sid(メールアドレス, パスワード)
t = Nico::Tags.new
t.read sid
t.save "tag_#{today}.csv"
ちなみに9/2~9/18で比較して上位10位までは変化なしでした。
1. ゲーム
2. アニメ
3. 音楽
4. エンターテイメント
5. MAD
6. 歌ってみた
7. プレイ動画
8. スポーツ
9. アイドルマスター
10. その他
ところで何順で並んでいるんだろう?
タグ新規登録数なのか、新規投稿動画のタグなのか、
マイリストやコメントや再生に紐付いてるタグなのか、
総数なのか、差分なのか、気になります。
学歴を横軸にとって、所得(勝ち組・負け組)を縦軸にとってみる。
高学歴の勝ち組が第1象限、
低学歴の勝ち組が第2象限、
低学歴の負け組が第3象限、
高学歴の負け組が第4象限となるね。
それぞれの言い分はこうだ。
高学歴の勝ち組は、学歴重要と言うね。
今の自分があるのは過去の着実な積み重ねあってのことって感じで。
低学歴の勝ち組は、学歴関係ねぇと言うね。
俺はやったぜ、お前らにもできるぜって感じで。
低学歴の負け組は、学歴重要と言うね。
俺だって学歴さえあればって感じで。
高学歴の負け組は、学歴関係ねぇって言うね。
だって俺全然しょぼいもん、て感じで。
つまり学歴論争における言い分はすべて、
「俺の過去と現状」について報告しているに過ぎないってことさ。
当社の商品の特徴は●と▲と■です。
顧客層は○と△と□です。
○層のために●という機能があります。
△層のために▲という機能があります。
□層のために■という機能があります。
差別化とは、何を持つか、誰を相手にするか、
ではない!・・・わけではないけれども、
そうやって足し算で考えていくと結局は何の特徴もない商品になっていたりします。
差別化戦略とは、
何を持たないか、誰を相手にしないか、なのです。
引き算で考えればはっきりします。
切り捨てるものが決められないとしたら、それは差別化できないということです。
ランチェスター戦略では、弱者ば差別化すべしと説いています。
強者は追随すべしと説いています。
弱者はなりふりかまってられない、
誰でもいいから買ってくれ、
そうやって相手にしない層を定義したがりません。
しかし、それが大きな罠なのです。
誰でもいいから、というのは強者がやることです。
強者がやることを真似ても力量で負けるに決まっています。
強者は誰でも相手にしてくれますから、
あえて相手を選ばないのです。
だから弱者は逆に、誰には売らないかを選ばなければいけないのです。
技術ネタは書くのに時間かかるし、
ネガティブなのばかりなのもなんか嫌だし、
本とか映画の感想は消化したあとすぐじゃないと書く気失せるし、
なんだろなー
基本毎日という習慣にしないとうまく回らない
けれども毎日書くネタもない
とりあえず最近、つかもう5ヶ月くらいになるかだけど
自由時間は優先的に永井先生の動画を見ている・・・
ほんと中毒だな。やれやれだぜ。
台風が来るということで今日は早めに撤収してきました。
強風でビニ傘がひっくり返って、コンパクトにしようとしたら指切って血が出たよ鬱だ。
でもってすみません傘放置しました。
最悪やって自分でも思うけどこれだけは勘弁してください。
壊れたビニ傘を自宅まで持参するって相当の精神力が必要だぞ。
僕には無理でした。
今日は仕事がひm、じゃなくて時間的に「ゆとり」があったのでGreaseMonkeyを使ってみました。
GreaseMonkeyはFirefoxのプラグインで、
ブラウズしているWebページをクライアントサイドでいじくるスクリプトを動かす環境です。
スクリプトはJavaScriptで書きます。
ちょうど仕事に役立つ題材があったのでそれを紹介します。
私は毎週月曜日の朝に、検索順位のチェック作業をしています。
検索順位のチェックツールにはいろいろありますが、
合ってなかったりすることが多々あるので信用ならんということで、
いつも目視でやっております。
それをYahoo、Google、MSNの3サイトで確認します。
ググ厨はしらないかもしれませんが、Yahooには検索順位が表示されます。
でもGoogleとMSNは表示されません。
なので順位を知りたければ上から数えるしかないんですよ。
うん下から数えてもいいよ。
これがね、めちゃくちゃ不便なのです。
Macのマウスにボタンが1個しかないことの次くらいに納得いかない。
たぶん世界のGoogle様のことだから何か意味があるんでしょうけどうざいです。
これを解決するスクリプトをGreaseMonkeyでちゃちゃっと作ってみました。
Googleだけのなら他の人が作ったのがあるんだけど、
ソースが微妙にわかりにくかったので自己流にアレンジしました。
// ==UserScript==
// @name display_rank
// @namespace http://eclipse.cspc.jp
// @description GoogleとMSNの検索結果に順位を表示
// @include http://search.msn.co.jp/*
// @include http://www.google.co.jp/*
// ==/UserScript==
(function() {
var url = window.location.href;
var m, first, es;
// MSNの場合
if (url.match(/^http:\/\/search\.msn\.co\.jp/)) {
// URLからページ内の1件目の順位を取得
m = url.match(/first=([0-9]+)/);
first = (m == null)? 1 : parseInt(m[1]);
es = document.getElementById('results').getElementsByTagName('h3');
}
// Googleの場合
else if (url.match(/^http:\/\/www\.google\.co\.jp/)) {
// URLからページ内の1件目の順位を取得
m = url.match(/start=([0-9]+)/);
first = (m == null)? 1 : parseInt(m[1]) + 1;
t_es = document.getElementById('res').getElementsByTagName('div');
es = new Array();
for (i = 0; i < t_es.length; i++)
if (t_es[i].className == 'g')
es.push(t_es[i]);
}
// 順位を追加
for (i = 0; i < es.length; i++)
es[i].innerHTML = '<span style="color:red;font-weight:bold">'
+ (first + i) + '. </span>' + es[i].innerHTML;
})();
こいつをdisplay_rank.user.jsとして保存して、
アドレスバーにファイルパスを打ち込めばインストールできます。
もちろんGreaseMonkeyは最初にインストールしておいてからね。
ここにあるから。
これでGoogleとMSNで検索したときにもYahooみたく順位が表示されるようになります。
コードはJavaScript/DOMの単純な例っていう感じじゃないかな。
以外に簡単に便利にできるんだなぁ、とちょっと感動しました。
また何かいい題材があったらGreaseMonkey使ってみよう。
PHPを生まれて初めて使ってみた。
でもCやPerlとほぼ同じなので特に面白くはない。
作ったのは、問い合わせフォームがあって
POSTすると確認画面にいってもう一度POSTすると
完了画面にいってメールが送信されるっていうただそれだけのプログラムですけどね。
POSTするデータの名前が日本語だとどうしても化ける現象のせいで半日つぶしちまったぜ・・・
結局あきらめて名前を半角英字にしたよ。負けた気分で実に不愉快であった。
プログラミングにかかる時間のうち、こういった本質以外の部分が多すぎる。
趣味プロだとどう回避しようが自分の勝手なのでいいんですけど。
大体inputタグのname属性を日本語になんて本来俺だったらやらないんだよ。
仕事続けてるとなるべく他人が作った物に対して手を加えないようになっていくんだよね。
それは自分を抑えるということでもあり他人を尊重するということでもあるし
責任範囲を明確にするためでもあるし必要最低限の労働で済ませようとするためでもある。
でもそのせいでとってもプログラミングがつまらくなってしまったりするんだよね。
あとさ、いまやプログラミングに検索という行為は欠かせないよね。
Googleなくなったらけっこう困るよね。
でもさでもさ、今日俺がはまったところなんてGoogleはまったく役に立たなかったぜ。
それどころか貴重な時間をむさぼり食いやがったんだ。
なぜかってもし検索できなかったらとっくにあきらめて他の道を行くという決断をしてたからさ。
一旦足を突っ込むと人間なかなかその足を切断する気になれないんだよね。
そしてずぶずぶと深い沼の中に埋もれていくわけだ。
Googleで検索すると大量にヒットするんだよ。
この中にはきっと自分の求めている情報があるはずだ、
もうちょっと探せば問題は解決できるよきっと、そう思えてしまう罠があるんだ。
実際、やつが把握している何十万件というデータの中には答えがあるのかもしれん。
でもそんなの関係ねぇってことさ。
下着が張り付くくらいまでにずぶぬれになって帰ってきた。
これはひどい。
やっべ書くことなすぐる。
そういうときはお気に入りのサイトでも貼りますか。
キャッチコピーって面白いですね。
それだけw
と思ったけど昨日ふと思いついたキャッチコピーを思い出したので書いておく。
「転職!転職!さっさと転職!」(騒音おばさんのリズムで)
いや、某エ○ジャパ○の秀逸なキャッチコピー
「転職は慎重に」に対して、
お前思ってないだろむしろ慎重になられたら商売上がったりなわけだがー
そうやって自分で煽っておいてまぁ落ち着けや、ていう汚さがけっこうシュールで好きです。
あからさまな建前キャッチに対して本音を表現してみました。
タイトルだけ書いてさて何か書くことあるだろうかと悩む。
とりあえず、入社する前に1年間は必ず続けることに決めたので、
その自分に対する義務は果たしました。
なので自分の中ではもういつ辞めてもOK。自分の中では、ねw
たかが1年と思うかもしれないけど、今の時代1年はそんなに短くなかったりします。
石の上にも三年と言う言葉がありますが、
三年にこだわりすぎると、時間がもったいなくなることもあると思います。
まぁひとそれぞれ適切な期間というものがあるのです。
でも今の新卒、二卒は、気に入らないとすぐやめる人が多いようです。
それは悪いことではないけれども、あまり良くないと思います。
特にサラリーマンを一生続けるつもりなら慎重にいくべきです。
それは「転職回数」というパラメータがけっこう重視されるという現実があるからです。
転職回数が多い人は、我が侭かもしれないとか、
問題を起こしやすいのではとか、対人関係が下手なのでは、
と想像されてしまう可能性があります。
履歴書と職務経歴書と2、3回の面接くらいでひとりの人間を
きちんと理解することなど不可能なので、
安直なパラメータと言えども決して甘く見るべきではないのです。
今すぐ辞めたくなる気持ちはわかります。
正直言いますと、僕なんて社会人になったその日から
こんな会社辞めてやると思わない日はないと言っても過言ではないくらいなものでw
でも同時に別の会社に入ったとしても同じように辞めたいと思うのは100%わかりきっています。
それはもう今の会社に転職する前もわかっていましたし、
仮に僕がトヨタに入ったとしてもGoogleに入ったとしてもはてなに入ったとしても
100%そういう風に思うという確信があります。
サラリーマンというのはそういうものだという覚悟がいるのです。
食い扶持を稼ぐということは、生き続けるということは、
つらいだろうし耐えなくてはいけないと思うんですよね。
別にサラリーマンが他よりつらいなんて言うつもりはなく、
サラリーマンでさえつらい、ということです。
そしてつらいということはダメじゃないんです。
ネガティブとポジティブってメタにとらえるとどっちがどっちだかわからなくなりますが、
ネガティブなものを否定することはつまらないことだと思います。
昨日の続きです。
もう一回挟もうとしたんだけど
面倒臭くなったのでのでCSV出力までやることにしました。
やりたいことは、
「ニコニコ動画のランキング一覧をファイルに書き出す」
だけです。
まずは書き出す情報を定義します。
module Nico
class Douga
attr_accessor(
:title, # タイトル
:url, # URL
:posted, # 投稿日
:length, # 動画の長さ(秒)
:mylist, # マイリスト登録数
:view, # 再生数
:res # コメント数
)
def self.head_csv
"URL,タイトル,投稿日,動画の長さ,マイリスト登録数,再生数,コメント数"
end
def to_csv
cell = Array.new(7)
cell[0] = @url
cell[1] = "\"#{@title}\""
cell[2] = @posted.strftime("%Y/%m/%d %H:%M:%S")
cell[3] = @length
cell[4] = @mylist
cell[5] = @view
cell[6] = @res
cell.join(",")
end
end # class
HTMLから取得したデータの動画情報1件分がDougaクラスのインスタンスに対応します。
データの設定はアクセッサ経由で外部でやります。
to_csvでCSVデータ1行分の文字列を返します。
続いてランキング一覧をクラス化します。
今回利用するランキングは「今までの合計」に限定しました。
取得するデータのマイリスト数、再生数、コメント数は投稿時点からの累積になります。
ランキングの種類としてはマイリスト順、再生順、コメント順の3パターンがありますが、
コンストラクタ(initialize)に種類(kind)を引数として渡すことで対応します。
マイリスト順ランキング:http://www.nicovideo.jp/ranking/mylist/total/all?page=1
再生順ランキング:http://www.nicovideo.jp/ranking/view/total/all?page=1
コメント順ランキング:http://www.nicovideo.jp/ranking/res/total/all?page=1
URLを見比べると、/raking/○○/total/allとなっているので、
○○の部分がmylistならマイリスト、viewなら再生、resならコメントだとわかります。
ランキングは1ページに100件まで載っています。
そしてページが10まであります。なので1000位まで取れるということになります。
Rankingクラスには一覧データ取得のreadメソッドと、
取得したデータをファイル出力するsaveメソッドを定義します。
class Ranking
def initialize (kind)
@kind = kind
@dougas = Array.new(1000) {Douga.new}
end
def read (sid)
Net::HTTP.start("www.nicovideo.jp", 80) do |http|
(1..10).each do |page|
warn "read #{@kind}:#{page}..."
response = http.get(
"/ranking/#{@kind}/total/all?page=#{page}",
"Cookie" => "user_session=user_session#{sid}")
doc = Hpricot.parse(response.body.tosjis)
i = (page - 1) * 100
doc.search("h3/a").each do |e|
@dougas[i].title = e.inner_text
@dougas[i].url = e[:href]
i += 1;
end
i = (page - 1) * 100
doc.search('p.TXT12[@style="color:#666;"]').each do |e|
@dougas[i].mylist = /([0-9,]+)/.match(e.inner_text)[1].delete(",").to_i
i += 1;
end
i = (page - 1) * 100
n = 0;
doc.search('td/p.TXT12/strong').each do |e|
case n % 4
when 0: @dougas[i].posted = DateTime.strptime(e.inner_text, "%Y年%m月%d日 %H:%M:%S")
when 1: @dougas[i].length = $1.to_i * 60 + $2.to_i if /(\d+)分(\d+)秒/ =~ e.inner_text
when 2: @dougas[i].view = e.inner_text.delete(",").to_i
when 3: @dougas[i].res = e.inner_text.delete(",").to_i
i += 1;
end
n += 1
end
end # each
end # start
end # def
def save (fname)
File.open(fname, "w") do |file|
file.puts Douga.head_csv
@dougas.each {|d| file.puts d.to_csv }
end # open
end # def
end # class
readメソッドが実際にHpricotを使ってスクレイピングしている部分になります。
Hpricotで使われる主なメソッドはsearchとatです。
searchはマッチする要素を全て取得します。
atはマッチする最初の要素のみ取得します。
まず1回目のsearchでh3タグの中のaタグを全てピックアップし、
タグ中の文字列を動画のタイトルとし、href属性をURLと判断します。
Hpricotの構文ではタグの階層を下っていくのに「/」が使われます。
i = (page - 1) * 100
doc.search("h3/a").each do |e|
@dougas[i].title = e.inner_text
@dougas[i].url = e[:href]
i += 1;
end
2回目のsearchでマイリスト数を取得します。
ちょっとややこしいですが、「p.TXT12[@style="color:#666;"]」の部分です。
「.」はCSS同様class属性を限定します。
また、[@hoge="..."]でhoge属性の値が...なものに限定します。
よって「p.TXT12[@style="color:#666;"]」は<p class="TXT12" style="color:#666;">...</p>にマッチします。
そしてマッチした文字列から数値部分のみ切り出してカンマを削除して整数変換して保持します。
i = (page - 1) * 100
doc.search('p.TXT12[@style="color:#666;"]').each do |e|
@dougas[i].mylist = /([0-9,]+)/.match(e.inner_text)[1].delete(",").to_i
i += 1;
end
3回目のsearchで残りの、投稿日時、動画の長さ、再生数、コメント数をまとめて取得します。
この4つはHTMLで同じレベルでタグ記述されているため、全部持ってきて、何個目かによって判断させています。
こういう時はおなじみのパターンですが、ループの中でインデックスの余りをとって処理を振り分けます。
1個目だったら投稿日時、2個目だったら動画の長さ、3個目だったら再生数、4個目だったらコメント数です。
でそれぞれ都合の良いように加工してから保持します。
Hpricotのタグ表現は、「td/p.TXT12/strong」となっているので、
tdタグの中の、pタグでclassがTXT12の中の、strongタグにマッチします。
i = (page - 1) * 100
n = 0;
doc.search('td/p.TXT12/strong').each do |e|
case n % 4
when 0: @dougas[i].posted = DateTime.strptime(e.inner_text, "%Y年%m月%d日 %H:%M:%S")
when 1: @dougas[i].length = $1.to_i * 60 + $2.to_i if /(\d+)分(\d+)秒/ =~ e.inner_text
when 2: @dougas[i].view = e.inner_text.delete(",").to_i
when 3: @dougas[i].res = e.inner_text.delete(",").to_i
i += 1;
end
n += 1
end
Nicoモジュールの最後に、セッションID取得処理を関数化します。
メールアドレスとパスワードを引数にとってセッションIDを返します。
中身は昨日のものと同じです。
def self.get_sid (mail, password)
sid = nil
https = Net::HTTP.new("secure.nicovideo.jp", 443)
https.use_ssl = true
https.start do |w|
data = "next_url=&mail=#{mail}&password=#{password}"
response = w.post("/secure/login?site=niconico", data, "Content-Length" => "#{data.length}")
sid = $1 if response["Set-Cookie"] =~ /user_session=user_session([0-9_]+)/
end
sid
end
end # module
ここまでのコードがNicoモジュールで、nico.rbという1ファイルになります。
次がこのモジュールを利用する側のコードです。
#! ruby -Ks
require 'net/https'
require 'date'
require 'kconv'
require 'rubygems'
require 'hpricot'
require 'nico'
today = Date.today.strftime("%Y%m%d")
sid = Nico::get_sid(メールアドレス, パスワード)
["mylist", "res", "view"].each do |kind|
r = Nico::Ranking.new(kind)
r.read sid
r.save "#{kind}_#{today}.csv"
end
これでマイリスト登録数・再生数・コメント数の3つの一覧CSVファイルが出力されます。
タスクスケジューラやcronで毎日回して、1ヶ月くらいとってから
Excelで集計すればなんか面白いグラフが見れるんじゃないかな、と期待しています。
釣り師的なタイトルで申し訳ないです。
今仕事でリスト取得ツールを作っているのですが、
その応用としてニコニコを実験場としたサンプルを作ってみることにします。
スクレイピングというのはHTMLパースのことですね。
RubyのスクレイピングライブラリとしてはHpricotがあります。
Hpricotの名前の由来は不明ですが、エイチプリコットと呼んでいます。
このHpricotはCSS風の書き方で気軽にスクレイピングできるのでとても使いやすいです。
とりあえずいきなりコード。
ニコニコのデフォルトランキング、本日のマイリスト登録数ランキング100から
動画のタイトルをひっぱってくるサンプルです。
#! ruby -Ks
require 'net/https'
require 'kconv'
require 'rubygems'
require 'hpricot'
sid = nil
https = Net::HTTP.new("secure.nicovideo.jp", 443)
https.use_ssl = true
https.start do |w|
data = "next_url=&mail=メールアドレス&password=パスワード"
res = w.post("/secure/login?site=niconico", data, "Content-Length" => "#{data.length}")
sid = $1 if res["Set-Cookie"] =~ /user_session=user_session([\d_]+)/
end
Net::HTTP.start("www.nicovideo.jp", 80) do |w|
res = w.get("/ranking/mylist/daily/all", "Cookie" => "user_session=user_session#{sid}")
doc = Hpricot.parse(res.body.tosjis)
doc.search("h3").each {|e| warn e.inner_text }
end
実行する前に、シェルで「gem install hpricot」とたたいて、
Hpricotをインストールしておいてください。
流れとしては、
1. 認証用サーバ(secure.nicovideo.jp)に接続
2. アカウント情報(メールアドレスとパスワード)を送信
3. クッキー(セッションID)を取得
4. 本サーバ(www.nicovideo.jp)に接続
5. 取得したセッションIDをくっつけて欲しいページをリクエスト
6. 欲しいページが手に入ったら煮るなり焼くなり
6番がHpricotでスクレイピングしてるところなんです。
上のサンプルだと次の2行になります。
doc = Hpricot.parse(res.body.tosjis)
doc.search("h3").each {|e| warn e.inner_text }
1行目で取得したHTMLをSJISにしてからスクレイピング用のHpricotオブジェクトに変換しています。
2行目で、対象HTMLの中からh3タグのみをピックアップして、h3の中身を文字列化して表示しています。
h3が動画のタイトルを表しているのはどうしてわかるのかと言うと、
該当ページのHTMLソースを見たからです。
当然、ニコニコの仕様が変われば動かなくなることもありえます。
この辺は人力です。人力なやり方のことをスクレイピングと言うのでしょう、多分。
今回のサンプルはただとってきて表示しただけなので何の役にも立ちませんが、
次回はもうちょっと詳しい情報を取ってきて加工してみることにします。
その次あたりで毎日CSV出力させてグラフ化とかしてみたいと思います。
