おはようございます、martinです。WC、初戦勝ちましたねぇ。正直期待していなかっただけに喜びも倍増といったところ。決勝トーナメント進出!なんて日が来るのでしょうか。
さて、今回は前回のアクセス解析の続きみたいなものです。前回のエントリーで、短縮URLの元を知るサイトとして、http://knowurl.com/ を紹介しましたが、他にもいくつかありますね。LongURL なんかもそうです。LongURLは、Firefoxの拡張版 もあるようですね。API も公開されているようでjQueryのプラグインとかもあるようです。APIがあるんで、ppBlogでも使える様なJavaScriptを書いても良いですが、仕組みは結構単純なので、外部のAPIに頼らずともppBlogのみで完結できそうです。
まずは、短縮URLがどのような仕組みになっているのか知る必要があります。短縮URLを提供しているサイトはいくつもあります(現時点で動いているのは bit.ly、j.mp、cli.gs、Short.ie、Idek.net、is.gd、sn.im、u.nuあたり)が、これら殆どのサイトでやっていることはリダイレクトです。PHPを使えば、その辺りの情報は簡単に取得出来ます。例えば、http://bit.ly/aKhZ1G は、http://p2b.jp/201006-get-html5-fileuploading-moduleというリンクの短縮形ですが、PHP経由でアクセスしてみると、リダイレクト先の情報などが入手出来ます。PHP5であれば、get_headers() 関数が使えます。便利ですね。この関数を使って以下を実行すると、
<?php $url = 'http://bit.ly/aKhZ1G'; print_r(get_headers($url, 1)); ?>大まかには、以下のようになります。
Array( [0] => HTTP/1.1 301 Moved /* Permanentlyと続くこともある */ [Location] => http://p2b.jp/201006-get-html5-fileuploading-module /* リダイレクト先がある! */ [MIME-Version] => 1.0 [Content-Length] => 313 [X-Powered-By] => PHP/5.1.6 )[Location]の項目に短縮URLの元リンクが収められていますね。なので、配列からこれを取り出せばOKです。じゃPHP5ではないサーバーではどうするか。fsockopen()関数 を使います。以下のような記述で行けるでしょう。
$url = 'http://bit.ly/aKhZ1G'; $_url = parse_url($url); $port = isset($_url['port']) ? $_url['port'] : 80; $host = isset($_url['host']) ? $_url['host'] : ''; $path = (isset($_url['path']) ? $_url['path'] : '/').(isset($_url['query']) ? '?'.$_url['query'] : ''); $request = "GET ".$path." HTTP/1.1¥r¥n"; $request .= "Host: ".$host."¥r¥n"; $request .= "Connection: Close¥r¥n¥r¥n"; if($fp = fsockopen($host, $port, $errno, $errstr, $timeout=3)){ stream_set_timeout($fp, 3); $ret = ''; fputs($fp, $request); do { $ret .= fgets ($fp, 4096); } while (strpos($ret, "¥r¥n¥r¥n") === FALSE); // ヘッダー部分で十分 fclose($fp); }
これを実行すると、以下のような感じになります。
HTTP/1.1 301 Moved Server: xxxx/0.7.42 Date: Tue, 15 Jun 2010 02:46:59 GMT Content-Type: text/html; charset=utf-8 Connection: close Set-Cookie:xxxx Location: http://p2b.jp/201006-get-html5-fileuploading-module /* これが欲しい */ MIME-Version: 1.0 Content-Length: 313
これから、Location:の部分を取り出す正規表現は、以下のような感じでしょうか。
$redirectURL = preg_replace('{^.+?Location:¥s([^¥n]+?)¥n.+$}s', '$1', $ret);これで、$redirectURLにhttp://p2b.jp/201006-get-html5-fileuploading-moduleという文字列が入ることになります。
以上のことをやると、リダイレクト先が分かるのでppBlogのアクセス解析に組み込んでみました。「リンク元」の項目で、短縮URLっぽいものには、下のショットにあるように「expand」というアイコンみたいなやつが付くようになります。
そしてこれをクリックすると、Ajax経由で情報をゲットして以下のような表示に変わります。
リダイレクト先があれば、これがその場で表示されます。これはリンクになっていますが、そのサイトへのリンクではなくて、グーグルでそのリンクを調べるようになっています。それで怪しげなサイトであればブラウザでアクセスするのを避けることが出来るわけです。
ちなみに、Ajax部分は、以下のような関数で実現しています。思ったよりシンプルに出来ました
var expand = function(url){ var target = o(oParts.evt.target); var loader = oParts.create('IMG').src('../Images/loader.gif'); /* ローディングアニメーション */ target.addAfter(loader); oParts.server.get('view.php?expand=' + url, function(ret){ /* これがAjax部分 */ loader.away(); if(ret == url){ target.css('color:gray; cursor: default').html('redirect 0').title('リダイレクトはありません').on('click', function(){}); } else { target.css('color:crimson; border-color: green').html('Redirect: <span onclick="googleIt(¥''+ret+'¥')" title="グーグルで検索">' + ret + '</span>'); } }); }
一応、これを実現するためのview.phpを添付しておきます。statディレクトリの既存のやつと置き換えればOKかと思います。前回添付したものの上位版になります。
今週末にppBlogの最新版配布を予定していますが、これはそのバージョンに組み込み予定です。
1. 初心者 — 2010/06/15@20:35:03
個人的要望です。
できれば、「生ログ」の「リンク元」にも、
「expand」の表示があれば、と思うしだいです。
…リンク元、生ログで辿るイラチなもので
技術的なこと、度外視したコメント、失礼しました。