- 2007/12/17
- Ruby
Google Chart という素晴らしいグラフAPIが公開されたので、記念にRubyを使って、指定したサイトのはてなブックマーク人気記事に付けられたタグをグラフ化することにしてみた。
今回は簡易版という事で、詳細な情報までは取得しにいっていないです。今後、バージョンアップしてもっと面白い形で見せられれば…と思います。
例として僕のブログで生成してみました。
- A : javascript
- B : tips
- C : *programming
- D : *web制作
今回学んだ事
ハッシュ(連想配列)のソート
#ハッシュ
tagArray = {"ruby" => 10, "php" => 5, "perl" => 8}
#値を降順で、同列の場合は値で
sortedArray = tagArray.to_a.sort{|a, b|
(b[1] <=> a[1]) * 2 + (a[0] <=> b[0])
}
RSSで複数の子要素がある場合の参照方法
rss = open(hatenaRssUri){ |file| RSS::Parser.parse(file.read) }
rss.items.each do |item|
#処理
end
item要素が複数ある場合は items 。dc_subjectが複数ある場合は dc_subjects など複数形にして .each で回す。
A-Zのアルファベットを生成する
(0..3).inject("A") do |res,i|
#chlArrayに英字[A-D]が格納される
chlArray << res;
res.succ
end
Google Chartのラベル用にAから始まるアルファベットを自動的に生成したくて検索してみたら、どう書く?orgに、まさに!なのがあったので参考にしてみました。
succは次の文字列を返すんですね。とても便利。
今回のソース
#!/usr/local/bin/ruby
#ライブラリ読み込み
require "cgi"
require 'open-uri'
require 'rss'
#cgiの処理
cgi = CGI.new
puts cgi.header(
"type" => "text/html",
"charset" => "UTF-8"
)
#変数初期化
result = ""
hatenaListUri = "http://b.hatena.ne.jp/entrylist?threshold=5&url="
hatenaRssUri = "http://b.hatena.ne.jp/entrylist?mode=rss&sort=hot&threshold=5&url="
errorMsg = ""
tagArray = {}
#グラフ用
chlArray = []
chdArray = []
chtArray = []
count = 0
etcValue = 0
googleChartLabel = ""
#入力データが空でなければ格納
if cgi["textdata"] != "" then
#入力されたURIをURLエンコード
inputUri = CGI.escape(cgi["textdata"])
#URIをセット
hatenaListUri += inputUri
hatenaRssUri += inputUri
#RSSをオープン
rss = open(hatenaRssUri){ |file| RSS::Parser.parse(file.read) }
rss.items.each do |item|
item.dc_subjects.each do |tag|
#ハッシュにすでにはいっているかどうかチェック
#if tagArray[tag.content] != nil then
if tagArray.key?(tag.content.downcase) then
tagArray[tag.content.downcase] += 1
else
tagArray[tag.content.downcase] = 1
end
end
end
#値を元にソート
sortedArray = tagArray.to_a.sort{|a, b|
(b[1] <=> a[1]) * 2 + (a[0] <=> b[0])
}
#展開
result = "<dl>\n"
sortedArray.each do |h|
result += '<dt>' + h[0].to_s + '</dt><dd>' + h[1].to_s + '個</dd>' + "\n"
if count < 4 then
#配列へ入力
chtArray << h[0].to_s
chdArray << h[1].to_s
count += 1
else
etcValue += h[1]
end
end
result += '</dl>'
#GoogleChartには2バイト文字があまり使えないので英字ラベルに置き換える
googleChartLabel = '<ul>'
(0..3).inject("A") do |res,i|
#ラベル用
chlArray << res;
#ラベル補助用
googleChartLabel += '<li>' + res + ' : ' + chtArray[i] + '</li>'
res.succ
end
googleChartLabel += '</ul>'
#GoogleChartURI
googleChart = '<img src="http://chart.apis.google.com/chart?cht=p3&chd=t:' + chdArray.join(',') + ',' + etcValue.to_s + '&chs=200x100&chl=' + chlArray.join('|') + '|etc">'
end
print <<EOM
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=UTF-8">
<style type="text/css">
dl{
width:50%;
}
dt{
margin:1em 0 0.5em 0;
}
dd{
margin:0 0 0 1em;
}
</style>
<title>Rubyではてなブックマーク人気記事RSSを解析してGoogle Chartで表示してみる</title>
</head>
<body>
<h1>Rubyではてなブックマーク人気記事RSSを解析してGoogle Chartで表示してみる</h1>
<h2>サイトURI</h2>
<form action="05.cgi" method="post">
<input type="text" name="textdata" value="">
<input type="submit" value="表示">
</form>
#{errorMsg}
<h3>仕様</h3>
<ul>
<li>はてなブックマークにつけられたタグの多い順4個を個別表示、以降のものは「etc」として合算</li>
<li>純粋にそのタグを付けた数(ユーザ数)ではない</li>
<li>5users以上のエントリのみ抽出</li>
</ul>
<h3>結果</h3>
<dl>
<dt>はてなブックマーク URI</dt>
<dd>#{hatenaListUri}</dd>
<dt>はてなブックマークRSS URI</dt>
<dd>#{hatenaRssUri}</dd>
</dl>
#{googleChart}
#{googleChartLabel}
#{result}
<p><a href="http://blog.tofu-kun.org/">ブログへ戻る</a></p>
</body>
</html>
EOM
- Newer: Rubyはじめました9:CGIでデバッグをする方法
- Older: 時間がいつの間にか過ぎていく