携帯のログ解析といったら無料ツールを使ってログを解析するか、高額な有料ツール・ASPを利用するしかないと思っていた方も多いのではないでしょうか。

EC、会員サービスなどを行っていないサイトには広告収入しかなく、ログ解析に月々何十万・何百万を出すことは無理です。(私が運営・管理しているサイトは月間PVが1億を超えるため、ASPを使うと…)

自分で解析するのもいいが、やはり第三者の解析、その上Googleのような名前が付くほうが信頼はされるのではないでしょうか…

そもそもGoogle AnalyticsのトラッカーはJavaScriptが有効でないと動作しません。ご存知のようにほとんどの携帯はJavaScriptを解釈できません。
Google AnalyticsがJavaScriptで何をしているかというと、ビーコンとして利用する画像のURLを生成しているだけです。

http://www.google-analytics.com/__utm.gif?utmwv=4.3&utmn=655538773&hogehogehoge

これなら自分でもできると思い、海外のサイトを参考にしながら独自のトラッキングコードを作りました。
(私はPHPよりJavaが得意なので自作コードはJavaです)

ビーコンURLを自分で生成するとRSSフィード、PDF、画像のトラッキングも可能です。基本的にはGoogle Analyticsのほぼ全ての機能を利用することができます。

以下、Javaのタグリブ、PHPのサンプルは一番下にあります。

Java版ではクッキーの日付、携帯端末IDなどビジター数を記録するための工夫も入れてます。今後は携帯端末のスクリーンサイズなども入れていこうと思います。

package com.manri.web.taglib;

import java.io.IOException;
import java.util.Random;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
import javax.servlet.jsp.tagext.TryCatchFinally;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class GoogleAnalyticsTag extends TagSupport implements TryCatchFinally {

private static final long serialVersionUID = 8778924015482341984L;

private static final Random RANDOM = new Random();

private String utmac;
private String utmhn;
private String uservar = "-"; // user defined variable
private String utmdt = "-";

private static final Log LOG = LogFactory.getLog(GoogleAnalyticsTag.class);

/**
* @see javax.servlet.jsp.tagext.TagSupport#doEndTag()
*/
@Override
public int doEndTag() throws JspException {

HttpServletRequest request = ((HttpServletRequest) pageContext.getRequest());
HttpServletResponse response = ((HttpServletResponse) pageContext.getResponse());
HttpSession session = request.getSession(false);

String now = String.valueOf(System.currentTimeMillis() / 1000);
String cookie = null;
String cookieFirstSet = null;
String cookiePrevSet = null;
String uniqueId = null;

if (session != null) {
cookie = (String) session.getAttribute("ga_cookie");
if (cookie == null) {
cookie = String.valueOf(10000000 + RANDOM.nextInt(88888888)); // random cookie number 10000000 - 99999999
session.setAttribute("ga_cookie", cookie);
}

cookieFirstSet = (String) session.getAttribute("ga_cookie_first");
if (cookieFirstSet == null) {
cookieFirstSet = now;
session.setAttribute("ga_cookie_first", cookieFirstSet);
}

cookiePrevSet = (String) session.getAttribute("ga_cookie_prev");
session.setAttribute("ga_cookie_prev", now);

uniqueId = (String) session.getAttribute("ga_unique_id");
/* if (uniqueId == null) {
uniqueId = MobileUtils.getUid(request);
if (StringUtils.isEmpty(uniqueId) || uniqueId.startsWith("error1:"))
uniqueId = null;
if (uniqueId != null)
session.setAttribute("ga_unique_id", uniqueId);
} */
} else {
cookie = String.valueOf(10000000 + RANDOM.nextInt(88888888)); // random cookie number 10000000 - 99999999
cookieFirstSet = now;
cookiePrevSet = now;
}

long utmn = 1000000000L + RANDOM.nextInt(888888888); // random request number 1000000000 - 9999999999
int random = 1000000000  + RANDOM.nextInt(1147483647); // number 1000000000 - 2147483647

String referer = request.getHeader("referer"); // referer url
if (StringUtils.isEmpty(referer))
referer = "-";

String utmp = (String) request.getAttribute(ServletAttributes.REQUEST_URI);
if (request.getQueryString() != null)
utmp += "?" + request.getQueryString();

String utmcs = response.getCharacterEncoding();
if (StringUtils.isEmpty(utmcs))
utmcs = "-";

if (StringUtils.isEmpty(utmdt))
utmdt = "-";

if (!StringUtils.isEmpty(uniqueId))
utmdt = uniqueId;

StringBuilder src = new StringBuilder("http://www.google-analytics.com/__utm.gif?utmwv=1");
src.append("&utmsr=-");
src.append("&utmul=-");
src.append("&utmje=0");
src.append("&utmfl=-");
src.append("&utmn=").append(utmn);
src.append("&utmhn=").append(utmhn);
src.append("&utmr=").append(referer);
src.append("&utmp=").append(utmp);
src.append("&utmac=").append(utmac);
src.append("&utmcs=").append(utmcs);
src.append("&utmdt=").append(utmdt);
src.append("&utmcc=__utma%3D");
src.append(cookie);
src.append(".");
src.append(random);
src.append(".");
src.append(cookieFirstSet);
src.append(".");
src.append(cookiePrevSet);
src.append(".");
src.append(now);
src.append(".2%3B%2B__utmb%3D");
src.append(cookie);
src.append("%3B%2B__utmc%3D");
src.append(cookie);
src.append("%3B%2B__utmz%3D");
src.append(cookie);
src.append(".");
src.append(now);
src.append(".2.2.utmccn%3D(referral)%7Cutmcsr%3D(direct)%7Cutmcmd%3D(none)%3B%2B__utmv%3D");
src.append(cookie);
src.append(".");
src.append(uservar);
src.append("%3B");

StringBuilder sb = new StringBuilder("<img");
sb.append(" src=\"" + src + "\"");
sb.append(" width=\"1\"");
sb.append(" height=\"1\"");
sb.append(" alt=\"\"");
sb.append("/>");

try {
pageContext.getOut().print(sb.toString());
} catch (IOException e) {
LOG.error("", e);
}

if (LOG.isDebugEnabled())
LOG.debug(sb.toString());

return super.doEndTag();
}

/**
* @see javax.servlet.jsp.tagext.TryCatchFinally#doCatch(java.lang.Throwable)
*/
@Override
public void doCatch(Throwable t) throws Throwable {
LOG.warn("", t);
}

/**
* @see javax.servlet.jsp.tagext.TryCatchFinally#doFinally()
*/
@Override
public void doFinally() {
}

/**
* @return the utmac
*/
public String getUtmac() {
return utmac;
}

/**
* @param utmac the utmac to set
*/
public void setUtmac(String utmac) {
this.utmac = utmac;
}

/**
* @return the utmhn
*/
public String getUtmhn() {
return utmhn;
}

/**
* @param utmhn the utmhn to set
*/
public void setUtmhn(String utmhn) {
this.utmhn = utmhn;
}

/**
* @return the uservar
*/
public String getUservar() {
return uservar;
}

/**
* @param uservar the uservar to set
*/
public void setUservar(String uservar) {
this.uservar = uservar;
}

/**
* @return the utmdt
*/
public String getUtmdt() {
return utmdt;
}

/**
* @param utmdt the utmdt to set
*/
public void setUtmdt(String utmdt) {
this.utmdt = utmdt;
}

}

PHP版
(海外サイトのもの、スクリーン解像度など付け加えたりどんどん改造できます)

$var_utmac=GOOGLE_ANALYTICS_CODE; //アカウント番号
$var_utmhn=www.hoge.com; //ドメイン名
$var_utmn=rand(1000000000,9999999999);//乱数
$var_cookie=rand(10000000,99999999);//cookie number 乱数
$var_random=rand(1000000000,2147483647); //乱数 2147483647以下
$var_today=time(); //today
$var_referer=$_SERVER['HTTP_REFERER']; // リファラー

$var_uservar=$storeinfo["storeid"]; // ユーザー変数
$var_utmp="http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];

$urchinUrl='http://www.google-analytics.com/__utm.gif?utmwv=1&utmn='.$var_utmn.'&utmsr=-&utmsc=-&utmul=-&utmje=0&utmfl=-&utmdt=-&utmhn='.$var_utmhn.'&utmr='.$var_referer.'&utmp='.$var_utmp.'&utmac='.$var_utmac.'&utmcc=__utma%3D'.$var_cookie.'.'.$var_random.'.'.$var_today.'.'.$var_today.'.'.$var_today.'.2%3B%2B__utmb%3D'.$var_cookie.'%3B%2B__utmc%3D'.$var_cookie.'%3B%2B__utmz%3D'.$var_cookie.'.'.$var_today.'.2.2.utmccn%3D(direct)%7Cutmcsr%3D(direct)%7Cutmcmd%3D(none)%3B%2B__utmv%3D'.$var_cookie.'.'.$var_uservar.'%3B';

$handle = fopen ($urchinUrl, "r");
$test = fgets($handle);
fclose($handle);

TrackBack URI | RSS feed for comments on this post

2 Responses

  1. Google Analyticsでモバイルのログ解析(PHPとリンク集) » バレで昼寝

    2008 12 月 13 1

    [...] この記事について追加情報です。 [...]

  2. kiyota

    2009 8 月 18 2

    携帯用のログ解析情報ありがとうございます。
    php版を参考にさせて頂きました。


Leave a reply