マルチ世代の情報発信

前回の記事でも触れたように、ケータイ、PC両方を使うマルチ世代の台頭が目立つようになってきた。自分には彼らが無意識にインターネットを利用するデバイスを使い分けているようにみえる。ケータイ向けサービスに絞って考えていく。


最近はケータイからできることがどんどん増えている。最近ではブログはもちろん、写真加工やデコメール作成もケータイから行うことができる。オンライン対戦ゲームやチャットもケータイでできるし、それでもPCからケータイ向けサービスを利用するユーザーは数多くいて、そこには接続速度や端末のスペック以外の理由があるように感じる。ケータイだけで完結するサービスももちろんあるが、ケータイ・PC双方を利用するサービスが今後増えていくのは間違いないはず。でも具体的にどういった使い分けがされていくのだろう。


まず、ブログ閲覧などの情報受信を行うデバイスは、外出中は間違いなくケータイからの利用がどんどん増える。PCがある環境では、好みの問題だと思う。情報の種類によってはPCではなくケータイを利用するユーザーも必ずいる。


次に情報発信。マルチ世代が発信している情報で一番多いのはブログや日記、プロフなど(プロフに関してはCNETの記事を参照)。これらは主にケータイから行われている。メールを一日に何十通もやり取りするマルチ世代からしたら、ケータイからの端末は一切苦にならない。特にTwitterはてなハイクみたいな一言系は常に身近にあるケータイの方が適している。ブログの記事が長文になる場合、ハイブリッド世代なら絶対にPCを利用すると思うが、マルチ世代の中にはケータイを利用する人もかなりいるはず。テキスト情報発信については完全に好みの問題じゃないかと感じる。


一方、画像加工やホームページ作成などの作業には使い分けが明確に発生するはず。PCを利用できるマルチ世代はこの種の情報発信に積極的で、無料ソフトやサービスを色々と使いこなしている。彼らは簡単な作業だったらケータイから、詳細に及ぶ設定はPCから作業しているようにみえる。


画像加工を例にとってみると、写真にフレームをつけたり文字を入れたりするのは数回ボタンを押すだけなので、ケータイからやった方が早い。一方、明度調整などの詳細なことをする場合は、ケータイからだと画面が小さい分やりづらい。画面の大きいPCで、Fotoflexerのようなインターフェースで作成する方が簡単だし時間もかからない。デュアルディスプレイにすると作業効率が上がる、と聞いたことがあるけれど、同じ原理なのでは。もちろん「簡単な作業」の定義がiphoneのようなタッチパネル、高速インターネット、優れたインターフェースの3拍子によって変化していくのは間違いないけれども。


簡単にまとめると、マルチ世代は自分のニーズに合わせてケータイとPCを使い分けていて、ケータイから簡単に情報発信し、PCから詳細な設定や加工を施すというスタイルが彼らを中心に浸透していくのではと思う。両方のデバイスの長所をうまく利用すれば、きっとサービスの幅と深さが増すはず。


※「マルチ世代」という表現はTech Mom From Silicon Valleyの海部さんから拝借。

モバイル世代からマルチ世代へ向けたウェブサービス

モバイルウェブについて面白い記事を発見。


Unbearable Lightness of Marketing:> matthewbuckland.com ? The mobile web: Why the future really is on the small screen


モバイルウェブはマスメディアである、との指摘が印象に残ったが、同時にケータイ向けウェブサービスについても考えさせられた。個人的な見解も踏まえて書いていく。


振り返ると、2006年がモバイル業界にとって転換期だったのだと思う。モバゲータウンがオープンして注目を集めたのも、ナンバーポータビリティでモバイルビッグバンとか言われていたのもこの年。ちょうどこの時期に前後してFlash Lite1.1を搭載した3G端末と定額制が普及して、色々な勝手サイトが誕生。そしてその無料でサービスを提供するというビジネスモデルが注目され始めた(無料サービスも出るについては今度フォーカスする予定)。


上の記事が書いているように、ケータイからのインターネットへのアクセスはPCからのそれを上回り続けると思う。携帯電話なら常に身近にあって場所を問わずに利用できる一方、PCは大多数の人にとっては特定の場所に行かなければ使えないデバイスの域を抜けきれていない。友だちの日記やニュースを見たり、スケジュールを管理したりなどはケータイがベストフィットしている気がする。


しかし、同時にPCからインターネットを利用する人も今後も増えると思う。


Tech Mom from Silicon Valley - 携帯ネット万能の世の中は、いつまでも続かない!んじゃないかな・・・


この記事にも書かれているように、現代の10代の多数はPCを使える、つまりPCの大画面と操作性の利点は熟知している。彼らの中にはPCが近くにあるときは大画面かつより快適な速度でサイトを見たい人もいるし、ケータイからだとやりにくい作業だけPCから行う人もいる。以下の記事がその現状を物語っている。


パソコンで携帯サイトを見る子供たち。そのワケは?


長くなってきたので、こういったモバイルに特化したサービスをどうマルチ世代向けにしていけるかは次回考えてみたいと思います。

PHPではてブスクレイピング+α

はてブPHPスクレイピングしてみた。

  • タグ検索結果からサイト名とURLを取得
  • 被ブクマ数を取得
  • XML形式で出力

というシンプルな内容です。

スクレイピングには、PHP凡庸スクレイピングライブラリを作ってみたで紹介されているライブラリを少々いじって利用。また、被ブクマ数取得にはAPIを使った。(参考サイト:はてなブックマーク件数取得API PHP版サンプル


ソース:

HatebScraper.Class.php

<?
class HatebScraper{
  
  function __construct($url="", $encoding="", $noQuery=""){
    
    (!empty($url)) ? $this->url = $url : $this->errors[] = "URLを設定してください";
  
    switch (true) {
      case empty($encoding)                  : $this->errors[] = "URLの文字エンコーディングを設定してください"; break;
      case eregi("SHIFT(-|_)JIS", $encoding) : $this->encoding = "SJIS-win"; break;
      case eregi("EUC-JP", $encoding)        : $this->encoding = "eucJP-win"; break;
      case eregi("UTF-8", $encoding)         : $this->encoding = "UTF-8"; break;
      case eregi("ISO-2022-JP", $encoding)   : $this->encoding = "ISO-2022-JP"; break;
      case eregi("JIS", $encoding)           : $this->encoding = "JIS"; break;
      case eregi("ASCII", $encoding)         : $this->encoding = "ASCII"; break;
      default                                : $this->errors[] = "不明なエンコーディングです";
    }
    
    if (empty($noQuery)) {
      if (!empty($_GET["tag"])) {
        $keyword = mb_convert_encoding($_GET["tag"], $this->encoding, "UTF-8");
        $this->keyword = rawurlencode($keyword);
        $this->url    .= $this->keyword;
      }
	  else {
        $this->errors[] = "検索キーワードを入力してください";
      }
	
	  if( !empty($_GET['page']) ){
		$this->page = 25 * $_GET['page'];
		$this->url .= "&of=" . $this->page;		
	  }

   	  switch($_GET['sort']) {
		case 'hot'  :
		case 'eid'  :
		case 'count':
						$this->url .="&sort=" . $_GET['sort'];
						break;
		default		: 	//do nothing
		}
    }
  }

  
  // HTMLを取得して、SimpleXMLObjectに変換
  function retrieve(){
    $html = $this->getHTML();
    
    //SimpleXMLオブジェクトに変換
    $this->xml = $this->html_to_simplexml($html);
  }
  
  // 要素を抽出
  function pickUpElement($xpath=""){
    (empty($xpath)) ? $this->errors[] = "対象の要素をXPath式で指定してください" : "";
    // 配列をセット
    foreach ($this->xml->xpath($xpath) as $item){
      $items[] = (string) str_replace("&amp;", "&", $item->asXML());
    }

    return $items;
  }

  // いったん、別のエンコードに変換したキーワードを再度UTF-8に変換し直す
  function convertKeyword(){
    $keyword = rawurldecode($this->keyword);
    $keyword = mb_convert_encoding($keyword, "UTF-8", $this->encoding);
    
    return $keyword;
  }
  
  // HTMLを取得
  function getHTML(){
    
    $client = new HTTP_Client();
    $client->setDefaultHeader(array('User-Agent' => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)'));
    $client->get($this->url);
    $result = $client->currentResponse();
    
    switch($this->encoding){
      case "SJIS-win" : $this->encoding_html = "shift_jis"; break;
      case "eucJP-win": $this->encoding_html = "euc-jp"; break;
      default         : $this->encoding_html = $this->encoding;
    }
    
    $html = $result["body"];
    $html = preg_replace("/".$this->encoding_html."/i", "utf-8", $html);
    $html = mb_convert_encoding($html, "UTF-8", $this->encoding);
    
    // コメントを削除
    $html = preg_replace("/<!--([^-]|-[^-]|--[^>])*-->/", "", $html);
    $html = str_replace("&", "&amp;", $html);
    
    if (preg_match("/<title>(.*)<\/title>/i", $html, $match)){
      $this->title = $match[1];
    }
    
    return $html;
  }
  
  // SimpleXMLオブジェクトに変換
  function html_to_simplexml($html_){
    
    // DOMDocumentの文字化け対策
    $html_ = preg_replace('/<title>/i',
                          '<meta http-equiv="content-type" content="text/html; charset=utf-8"><title>',
                          $html_);
    
    @$dom = new DOMDocument("1.0", "utf-8");
    @$dom->loadHTML($html_);
    
    // DOMをSimpleXMLへ変換
    $ret = simplexml_import_dom($dom);
    
    $str = $ret->asXML();
    
    // XML宣言付与
    if (true !== preg_match('/^<\\?xml version="1.0"/', $str)) {
      $str = '<?xml version="1.0" encoding="UTF-8"?>' . "\n" . $str;
    }
    
    $ret = simplexml_load_string($str);
    
    return $ret;
  }
  
  // エラーがあった場合、エラーメッセージを含む文字列を返す
  function isError(){
    if (count($this->errors) > 0) {
      foreach($this->errors as $error) {
        $msg .= "<li>{$error}</li>\n";
      }
      
      echo "<ul>". $msg ."</ul>";
    }
	else {
      return false;
    }
  }
}

?>


hateb.php

<?php

//$_GETにtag, page, sortを指定可能

require_once "HTTP/Client.php";
require_once "XML/RPC.php";
require_once "HatebScraper.Class.php";

$scraper = new HatebScraper("http://b.hatena.ne.jp/t?tag=", "UTF-8");

if ( empty($_GET["tag"]) ) { echo "no tag"; exit; }

// XMLに変換して格納(その際に不必要なタグを除去)
$scraper->retrieve();

// 要素を抽出して、変数に代入
$titles = $scraper->pickUpElement('//a[@class="bookmark"]');
$urls = $scraper->pickUpElement('//a[@class="bookmark"]/@href');
$count  = count($titles);

//Get Hateb User
$params = array();

for($i=0;$i<$count;$i++) {
//strip href part
$urls[$i] = strstr($urls[$i], '"');
$urls[$i] = substr($urls[$i], 1, (strlen($urls[$i])-2) );

$params[$i] = new XML_RPC_Value($urls[$i], 'string');
}


$msg = new XML_RPC_Message('bookmark.getCount', $params);
$cli = new XML_RPC_Client('/xmlrpc', 'b.hatena.ne.jp');

$resp = $cli->send($msg);

if (!$resp) {
    echo 'Communication error: ' . $cli->errstr; exit;
}

if( !$resp->faultCode() ) {
    $data = XML_RPC_decode( $resp->value() );
}
else {
    var_dump($resp->faultCode());
    var_dump($resp->faultString()); exit;
}
	
$sites = array();

for($i=0;$i<$count;$i++) {
	$sites[$i] = array(
						'title' => $titles[$i],
						'url'	=> $urls[$i],
						'user'	=> $data[$urls[$i]]
					 );
}

// キーワードをUTF-8に戻す
$scraper->keyword = $scraper->convertKeyword();


// Output XML
header("Content-Type: text/xml;charset=utf-8");
echo '<?xml version="1.0"?>'."\n";
echo "<results>";

if ($scraper->isError() !== false) {
  $scraper->isError();
}
else {
  $msg = '';
  
  for ($i=0; $i<$count; $i++){
    $msg .= '<result id="'. ($i + 1) .'">';
    $msg .= "<title>". strip_tags($sites[$i]['title'])."</title>";
	$msg .= "<url>".strip_tags($sites[$i]['url'])."</url>";
	$msg .= "<user>".strip_tags($sites[$i]['user'])."</user>";
    $msg .= "</result>";
  }
  
  echo html_entity_decode($msg);
}

echo "</results>";
?>

hateb.php?tag=Tag&page=1&sort=count

みたいに実行できます。
APIがなくてもスクレイピングを駆使すれば色々作れそう。

PCから見るFlash Liteコンテンツ

今年2月のAdobeからの発表によると、4.5億台のデジタル端末(携帯電話以外を含む)がFlash Liteを搭載しているらしい。Flash Liteは海外でもとても注目されていて、世界トップシェアを誇るSamsungやLGの携帯端末の一部インターフェイスFlash Liteで作成されている。

日本ではFlash Liteを使用した携帯サイトも最近は増えているし(日清やGatsbyが有名)、モバゲーのゲームの大半もFlash Liteで開発されている。様々な分野でのFlash Liteの浸透が目立つ。

今回はPCから閲覧できるサイトを少しピックアップ。

待ち受けやゲーム、アプリケーションのサンプルが閲覧できます。個人的にはMTVのインターフェースが気になる。

デザイナー系Flash待ち受け画像がたくさん展示されています。携帯からダウンロード可能です。

海外の会社のページ。"MOBILE"をクリックした後、ウィンドウ内のApplicationsやWallpaperをクリックすると、サンプルが見れる。

oxygen-メモリ使用量やFPSレートを表示するFlash Liteコンポーネント

OxygenというFlash Lite用ツールキットが公開された。FPSやメモリ、バッテリー残量をFlash Liteコンテンツに表示するコンポーネントが含まれている。実機テストの時に重宝しそう。

無料でこちらで配布中(英語):
Oxygen - The Flash Lite Developers Kit


同梱されているコンポーネント

  • FPS-Meter: FPS値を表示。アニメーション最適化の時に便利。
  • Mem-Meter: 空きメモリを表示。
  • Battery Meter: 電池残量を表示。
  • Signal Meter: 電波状況を表示。


Flash 8やFlash CS3でAdobe Extension Managerが入っている人は、

  1. zipファイルを解凍後、同梱されているOxygen Toolkit.mxpをダブルクリック
  2. Flash 8もしくはFlash CS3のメニュバーからウィンドウ→共有ライブラリをクリック
  3. ライブラリウィンドウが表示されるので、利用したいコンポーネントをステージへドラッグ

で、swfを端末かDevice Centralで確認できます。