ブックマークレット+円グラフでサイト解析してみる

こんにちは。松田です。
最近巷では、MacのCM→べつやくメソッドの流れで円グラフがちょっとしたブームらしいですね。
というわけで今回はその流行に乗っかって、ブックマークレットを使ってJpGraphで円グラフを表示させてみたいとおもいます。表示させる内容はいろいろと試してみた結果、最も簡単な「サイト内で使用されているHTMLタグ数」にしてみたいと思います。

「どうせならリリースしたてのJSChart使えよ!」という声が社内から聞こえてきそうですが、ブックマークレットに<script>タグが絡んでくると面倒そうなのと、実際途中まで作ってみて頓挫した経験を踏まえて、今回は素直にJpGraphを使って作成します。

今回作成したブックマークレットは下のリンクです。右クリックしてお気に入りに保存して使用してみてください。
 タグ解析ブックマークレット 

このブックマークレットの処理のおおまかな流れは以下の通りです。

ブックマークレットでサイトのURLをスクリプトに投げる
       ↓
PHPスクリプトで指定されたURLからHTMLを取得
       ↓
サイトを構成するHTMLタグを調べてカウント
       ↓
JpGraphで解析結果を出力

まずはブックマークレットの基本から
ブックマークレットとは、お気に入り(ブックマーク)にURLの代わりにJavaScriptのコードを仕込んでおき、サイト内で動作する機能を実現するモノの総称です。はてぶで使われている「はてなブックマークに追加」のブックマークレットなどは使ったことがある人も多いと思います。
ただ、自分もブックマークレットを使ったことはあっても、作ったことは無かったので、基礎はほとんど下記のサイトで勉強しました。ブックマークレット作成の基礎が習得できます。必読です。
Bookmarklet - ブックマークレットを作成する際のポイント

簡単なブックマークレットを作ってみる
上記を読んだら、まずは基本中の基本、ブックマークレットで「Hello World!」を出してみたいと思います。
上のサイトからブックマークレットのサンプルをコピペしてきてそれを元に作ってみます。

・サンプルのコピペ


javascript:(
    function(){ // 無名ファンクションの定義開始
        var contents='out';
        function abc(){
            var contents='in';
            alert(contents)
        };
        abc();
        alert(contents);
    }
)(); // 無名ファンクションを呼び出す

コメントとfunction()内のいらない処理を消してきれいに・・・


javascript:(
    function(){
    }
)();

これがブックマークレットのテンプレートになりそうです。

ここに「Hello World!」を出力するalert()文を付けて・・・


javascript:(
    function(){
        alert('Hello World!');
    }
)();

最後に余計なスペースと改行を消して一行にまとめる。


javascript:(function(){alert('Hello World!');})();

完成!

上のスクリプトを適当な名前を付けてお気に入りに登録。
ここを右クリック→お気に入りに登録でも可

これで作成したお気に入りをクリックすれば、「Hello World!」が表示されるハズです。


表示された!

ブックマークレットで画像を表示させてみる
ここまで出来たら次のステップへ。
JpGraphを使用されたことのある方はご存知かもしれませんが、JpGraphではグラフを出力する際に、<img>タグを使用して出力します。
例:<img src="draw_graph.php" alt="graph" />

今回もこんな感じでJpGraphを使用することになるので、ひとまずブックマークレットで<img>タグを出力するところから作ってみます。グラフを出力する draw_graph.phpはまだ作成していないので、代わりにアシアルのサイトのトップにあるロゴ画像を表示させてみましょう。

<img src="http://www.asial.co.jp/css/header2.png" alt="asial_logo" />

JavaScriptでタグを出力する方法は、document.createElementでタグのエレメントを生成し、document.body.appendChild();でbodyに追加する方法と、document.body.innerHTML にタグの構文を直接追加する方法がありますが、innerHTMLでは埋め込んだJavaScriptが動作しないことがあるので、createElementを使用して作成します。

・createElementを使用して<img>タグを生成


javascript:(
    function(){
        var el=document.createElement('img'); 
        el.alt='graph';
        el.src='http://www.asial.co.jp/css/header2.png'; 
        document.body.appendChild(el); 
    }
)();

・一行にまとめる


javascript:(function(){var el=document.createElement('img');el.alt='graph';el.src='http://www.asial.co.jp/css/header2.png'; document.body.appendChild(el);})();

これを先ほどと同様にお気に入りに追加し、クリックしてみましょう。
ページの一番下にアシアルのロゴ画像が表示されます。
ここを右クリック→お気に入り追加でも可

この位置だと画像が見づらいので、無理やり場所を変えて一番上まで持ってきたいと思います。
表示位置を強制的に指定するために、<img>タグのstyle属性で、position='absolute'、left='10px'、top='10px'を指定し、サイトの左上(10px, 10px)の場所に画像を表示させます。


javascript:( function() { 
var el=document.createElement('img'); 
el.alt='graph'; 
el.src='http://www.asial.co.jp/css/header2.png'; 
el.style.position='absolute';
el.style.left='10px';
el.style.top='10px';
document.body.appendChild(el); 
} )(); 

これでもう一度ブックマークレットを作成し、実行すると、ロゴ画像が左上のほうに表示されます。

出た出た。

JpGraphでグラフを生成
ブックマークレットの基本だけでだいぶ長くなってしまいましたが、次はロゴ画像の代わりにグラフが表示されるように作成します。
ここで、JpGraphでグラフを出力するスクリプト draw_graph.php を作りますが、今回はそのついでに、JpGraphでグラフを作成する最も簡単でスピーディーな方法をお教えします。

1.弊社サイト内のJpGraph サンプル集を開く

2.表示されたグラフの中から、作りたいグラフに最も近いものを選んでクリック

3.そのグラフのソースコードが表示されるのでそれをコピペ

ね、簡単でしょう?

今回は基本的な円グラフさえ出せればいいので次のサンプルを利用しました。

その前にブックマークレットからURLを渡せるように修正
次に、グラフに表示させる値をサイトのHTMLから作成しないといけないのですが、サイトのURLを受け取る仕組みを作っていなかったので、ブックマークレットをちょっと改良します。ここではdraw_graph.phpにGETでURLを渡すことにします。現在表示しているページのURLは、location.hrefで取得することができるので以下のようになります。


javascript:( function() {
    var el=document.createElement('img'); 
    el.alt='graph';
    el.src='http://www.asial.co.jp/blog/scripts/176/draw_graph.php?url='+location.href;
    el.style.position='absolute';
    el.style.left='10px';
    el.style.top='10px';
    document.body.appendChild(el); 
} )();

JpGraphでグラフを生成の続き
draw_graph.php内でURLを受け取り、file_get_contents()でHTMLを取得します。


<?php
$url = $_GET["url"];
$contents = file_get_contents($url);

これをpreg_match_allにかけてタグを取得します。こんな感じ?


preg_match_all("/<(.+?)>/i", $contents, $matches);

この処理だけだと、$matches[1]には、閉じタグ(</p>とか)や、タグの要素(class="page"とか)も全て取り込んでしまうので、それらは無視するようにうまいこと処理します。
あとはこれをJpGraphを使って出力するだけです。

・draw_graph.php


<?php
include ("/lib/jpgraph/src/jpgraph.php");
include ("/lib/jpgraph/src/jpgraph_pie.php");
$url = $_GET["url"];
$contents = file_get_contents($url);
preg_match_all("/<(.+?)>/i", $contents, $matches);
// うまいこと処理
$tag_list = array();
foreach ($matches[1] as $key => $value) {
  if (substr($value, 0, 1) != "/") {
    list($tag, $tmp) = explode(" ", $value);
    $tag_list[$tag]++;
  }
}
// タグの個数順にソート
$new_tag_list = array();
foreach ($tag_list as $tag => $value) {
  $new_tag_list[] = array("tag" => $tag, "value" => $value);
}
for($i = 0; $i < count($new_tag_list); $i++) {
  for($j = $i+1; $j < count($new_tag_list); $j++) {
    if ($new_tag_list[$i]["value"] < $new_tag_list[$j]["value"]) {
      $tmp = $new_tag_list[$i];
      $new_tag_list[$i] = $new_tag_list[$j];
      $new_tag_list[$j] = $tmp;
    }
  }
}
// 値取得
foreach ($new_tag_list as $data) {
  $tagname_list[] = $data["tag"];
  $value_list[] = $data["value"];
  $label_list[] = $data["tag"] . ":" . $data["value"];
}
$graph = new PieGraph(400,300);
$plot = new PiePlot($value_list);
$plot->SetLabels(array_reverse($label_list));
$plot->value->SetFont(FF_ARIAL,FS_NORMAL,9);
$plot->value->Show();
$graph->Add($plot);
$graph->Stroke();
?>

やった。完成。
これでブックマークレットをクリックするとそのサイトのタグ解析結果がグラフで表示されます。

完成版タグ解析ブックマークレット


javascript:(function() {var el=document.createElement('img');el.alt='graph';el.src='http://www.asial.co.jp/blog/scripts/176/draw_graph.php?url='+location.href;el.style.position='absolute';el.style.left='10px';el.style.top='10px';document.body.appendChild(el);})();

完成版タグ解析ブックマークレット:右クリック→お気に入り登録

・実行結果

どうやらうちのサイトは<a>タグと<div>タグが多いようです。
※ちょっぴり解析結果が怪しいです。解析スクリプト間違ってるかも・・・

本当はHTMLのテキストを形態素解析して使用されている単語のジャンルを分類し、その結果を円グラフに表示する、ってのを作りたかったんですが、形態素解析ソフトのインストールに失敗しまくり眠気もピークに達してきたのでここまでにします。↑はヒマを見つけてそのうち作ってみます。

それではおやすみなさい。。