Paradigm Shift Design

ISHITOYA Kentaro's blog.

はてなキーワードの情報を取得するクラス

ありそうなんだけど、Services_Hatenaを見てもなくて、探すのも面倒なので書いてみた。SimpleXMLが全くシンプルじゃないのを忘れていて時間がかかってしまった・・・orz


今作ってる奴用に、データがあるかないかだけを取得しているので、キーワードの複数の意味を取得するようなものにはなっていません。

<?php
class Hatena_HatenaKeyword{
    const URI = "http://search.hatena.ne.jp/keyword?word=%s&mode=rss&ie=utf8&page=1";
    const HATENA_NS = "http://www.hatena.ne.jp/info/xmlns#";
    const HATENA_NS_PREFIX = "hatena";
    const OPENSEARCH_NS = "http://a9.com/-/spec/opensearchrss/1.0/";
    const OPENSEARCH_NS_PREFIX = "openSearch";
    
    public static function fetch($keyword){
        $encoded = urlencode($keyword);
        $uri = sprintf(self::URI, $encoded);

        $data = simplexml_load_file($uri);
        $data->registerXPathNamespace(self::HATENA_NS_PREFIX, self::HATENA_NS);
        $data->registerXPathNamespace(self::OPENSEARCH_NS_PREFIX, self::OPENSEARCH_NS);

        $count =
            self::getNSElementData($data->channel, self::OPENSEARCH_NS_PREFIX,
                                   'totalResults');
        $result = array();
        $result["count"] = $count;
        foreach($data->item as $item){
            if($item->title == $keyword){
                $result["name"] = (string)$item->title;
                $result["uri"] = (string)$item->link;
                $result["readings"] =
                    self::getNSElementData($item, self::HATENA_NS_PREFIX, "furigana");
                $result["score"] =
                    self::getNSElementData($item, self::HATENA_NS_PREFIX, "score");
                $result["found"] = true;
                break;
            }
        }
        if(isset($result["name"]) == false){
            $result["found"] = false;
        }
        return $result;
    }
    protected static function getNSElementData($node, $ns, $name){
        $values = $node->xpath("$ns:$name");
        if(empty($values)){
            return null;
        }
        return (string)$values[0];
    }
}
?>

で、

<?php
var_dump(Hatena_HatenaKeyword::fetch("Twitter"));
var_dump(Hatena_HatenaKeyword::fetch("Hage"));
?>

とすると

array(6) {
  ["count"]=>
  string(1) "1"
  ["name"]=>
  string(7) "Twitter"
  ["uri"]=>
  string(37) "http://d.hatena.ne.jp/keyword/Twitter"
  ["readings"]=>
  string(15) "ついったー"
  ["score"]=>
  string(2) "70"
  ["found"]=>
  bool(true)
}
array(2) {
  ["count"]=>
  string(1) "1"
  ["found"]=>
  bool(false)
}

のようなデータを得ることができます。