具体步骤分为数据采集脚本,数据收取服务,数据分析脚本,数据存储服务

采集脚本一般有两种形式,一种是简单的页面插入一个图片进行请求,一种是复杂的动态生成js标签,引入一段js(这时采集服务器会网往客户端写cookie),js采集浏览器数据与cookie,然后发送请求。

数据收取服务一般为web服务,可以是apache,nginx,或者swoole,这里主要看采集的压力,适当做负载均衡,可以爱脚本端做,也可以在服务端做,注意客户端ip的穿透。

脚本分析可以使用任何脚本,例如php,python。

数据存储分为两部,一个是采集数据的存储,一个是分析之后的数据的存储,一般来讲原始数据是需呀保留的,所以原始数据采集可以使用文本保存在单机,或者使用redis等可固话的存储容器保存。

  选用不同的形式对扩展以后的服务有一定的影响,暂且不谈,在pv/uv只有几百万的站点,或者几千万的站点web服务压力基本不大,每天的原始数据存储会有几百M。

  细节上可以使用不同的技术,例如加入memcached缓存,使用多进程多线程等

我使用的方案是使用nginx做采集web服务器,使用js脚本采集数据,采集的数据按五分钟分500个文件存储避免文本的冲突,然后php五分钟定期处理数据,统计结果记入redis保存。

js采集脚本如下:

(function () {
var c = {
id: '{$sid}',
dm: [
{$dm}
],
nv: {$nv},
vdur: {$vdur},
age: {$age},
rec: {$rec},
uid: {$uid},
cf : {$cf}
};
var l = !,
m = null,
n = !;
var p = function () {
function a(a) {
/["\\\x00-\x1f]/.test(a) && (a = a.replace(/["\\\x00-\x1f]/g, function (a) {
var b = d[a];
if (b) return b;
b = a.charCodeAt();
return '\\u00' + Math.floor(b / ) .toString() + (b % ) .toString()
}));
return '"' + a + '"'
}
function b(a) {
return > a ? '' + a : a
}
var d = {
'': '\\b',
'\t': '\\t',
'\n': '\\n',
'\f': '\\f',
'\r': '\\r',
'"': '\\"',
'\\': '\\\\'
};
return function (d) {
switch (typeof d) {
case 'undefined':
return 'undefined';
case 'number':
return isFinite(d) ? String(d) : 'null';
case 'string':
return a(d);
case 'boolean':
return String(d);
default:
if (d === m) return 'null';
if (d instanceof Array) {
var f = [
'['
],
h = d.length,
k,
g,
u;
for (g = ; g < h; g++) switch (u = d[g], typeof u) {
case 'undefined':
case 'function':
case 'unknown':
break;
default:
k && f.push(','),
f.push(p(u)),
k =
}
f.push(']');
return f.join('')
}
if (d instanceof Date) return '"' + d.getFullYear() + '-' + b(d.getMonth() + ) + '-' + b(d.getDate()) + 'T' + b(d.getHours()) + ':' + b(d.getMinutes()) + ':' + b(d.getSeconds()) + '"';
k = [
'{'
];
for (h in d) if (Object.prototype.hasOwnProperty.call(d, h)) switch (g = d[h], typeof g) {
case 'undefined':
case 'unknown':
case 'function':
break;
default:
f && k.push(','),
f = ,
k.push(p(h) + ':' + p(g))
}
k.push('}');
return k.join('')
}
}
}();
function q(a, b) {
var d = a.match(RegExp('(^|&|\\?|#)(' + b + ')=([^&#]*)(&|$|#)', ''));
return d ? d[] : m
}
function v(a) {
return (a = (a = a.match(/^(https?:\/\/)?([^\/\?#]*)/)) ? a[].replace(/.*@/, '') : m) ? a.replace(/:\d+$/, '') : a
};
function w(a, b) {
if (window.sessionStorage) try {
window.sessionStorage.setItem(a, b)
} catch (d) {
}
}
function x(a) {
return window.sessionStorage ? window.sessionStorage.getItem(a) : m
};
function y(a, b, d) {
var e;
d.f && (e = new Date, e.setTime(e.getTime() + d.f));
document.cookie = a + '=' + b + (d.domain ? '; domain=' + d.domain : '') + (d.path ? '; path=' + d.path : '') + (e ? '; expires=' + e.toGMTString() : '') + (d.r ? '; secure' : '')
}; function z(a, b) {
var d = new Image,
e = 'mini_yp_log_' + Math.floor( * Math.random()) .toString();
window[e] = d;
d.onload = d.onerror = d.onabort = function () {
d.onload = d.onerror = d.onabort = m;
d = window[e] = m;
b && b(a)
};
d.src = a
}; var A;
function D() {
if (!A) try {
A = document.createElement('input'),
A.type = 'hidden',
A.style.display = 'none',
A.addBehavior('#default#userData'),
document.getElementsByTagName('head') [].appendChild(A)
} catch (a) {
return n
}
return l
}
function E(a, b, d) {
var e = new Date;
e.setTime(e.getTime() + d || );
try {
window.localStorage ? (b = e.getTime() + '|' + b, window.localStorage.setItem(a, b)) : D() && (A.expires = e.toUTCString(), A.load(document.location.hostname), A.setAttribute(a, b), A.save(document.location.hostname))
} catch (f) {
}
}
function H(a) {
if (window.localStorage) {
if (a = window.localStorage.getItem(a)) {
var b = a.indexOf('|'),
d = a.substring(, b) - ;
if (d && d > (new Date) .getTime()) return a.substring(b + )
}
} else if (D()) try {
return A.load(document.location.hostname),
A.getAttribute(a)
} catch (e) {
}
return m
};
function I(a, b, d) {
a.attachEvent ? a.attachEvent('on' + b, function (b) {
d.call(a, b)
}) : a.addEventListener && a.addEventListener(b, d, n)
};
function N(a, b) {
return '[object ' + b + ']' === {
}.toString.call(a)
};
function Z(a, b) {
a = '.' + a.replace(/:\d+/, '');
b = '.' + b.replace(/:\d+/, '');
var d = a.indexOf(b);
return - < d && d + b.length == a.length
}
function wa(a, b) {
a = a.replace(/^https?:\/\//, '');
return == a.indexOf(b)
}
function Y(a) {
for (var b = ; b < c.dm.length; b++) if ( - < c.dm[b].indexOf('/')) {
if (wa(a, c.dm[b])) return l
} else {
var d = v(a);
if (d && Z(d, c.dm[b])) return l
}
return n
}
function ra(a) {
for (var b = [
], d = , e = R.length; d < e; d++) {
var f = R[d],
h = a.a[f];
'undefined' != typeof h && '' !== h && b.push(f + '=' + encodeURIComponent(h))
}
d = a.a.et;
( === d || === d) && a.a.rt && b.push('rt=' + encodeURIComponent(a.a.rt));
return b.join('&')
}
function na() {
var a = 'Yp_cv_' + c.id;
try {
if (y(a, '', {
domain: la(),
path: ma(),
f: -
}), window.sessionStorage && window.sessionStorage.removeItem(a), window.localStorage) window.localStorage.removeItem(a);
else if (D()) try {
A.load(document.location.hostname),
A.removeAttribute(a),
A.save(document.location.hostname)
} catch (b) {
}
} catch (d) {
}
}
function ma() {
for (var a = , b = c.dm.length; a < b; a++) {
var d = c.dm[a];
if ( - < d.indexOf('/') && wa(document.location.href, d)) return d.replace(/^[^\/]+(\/.*)/, '$1') + '/'
}
return '/'
}
function la() {
for (var a = document.location.hostname, b = , d = c.dm.length; b < d; b++) if (Z(a, c.dm[b])) return c.dm[b].replace(/(:\d+)?[\/\?#].*/, '');
return a
}
function pa() {
var a = x('Yp_unsent_' + c.id);
if (a) for (var a = a.split(','), b = , d = a.length; b < d; b++) z(Q + '//' + decodeURIComponent(a[b]) .replace(/^https?:\/\//, ''), function (a) {
X(a)
})
}
function X(a) {
var b = x('Yp_unsent_' + c.id) || '';
b && ((b = b.replace(RegExp(encodeURIComponent(a.replace(/^https?:\/\//, '')) .replace(/([\*\(\)])/g, '\\$1') + '(%26u%3D[^,]*)?,?', 'g'), '') .replace(/,$/, '')) ? w('Yp_unsent_' + c.id, b) : window.sessionStorage && window.sessionStorage.removeItem('Yp_unsent_' + c.id))
}
function qa(a, b) {
var d = x('Yp_unsent_' + c.id) || '',
e = a.a.u ? '' : '&u=' + encodeURIComponent(document.location.href),
d = encodeURIComponent(b.replace(/^https?:\/\//, '') + e) + (d ? ',' + d : '');
w('Yp_unsent_' + c.id, d)
}
(function () {
function a() {
if (!a.b) {
a.b = l;
for (var b = , d = e.length; b < d; b++) e[b]()
}
}
function b() {
try {
document.documentElement.doScroll('left')
} catch (d) {
setTimeout(b, );
return
}
a()
}
var d = n,
e = [
],
f;
document.addEventListener ? f = function () {
document.removeEventListener('DOMContentLoaded', f, n);
a()
}
: document.attachEvent && (f = function () {
'complete' === document.readyState && (document.detachEvent('onreadystatechange', f), a())
});
(function () {
if (!d) if (d = l, 'complete' === document.readyState) a.b = l;
else if (document.addEventListener) document.addEventListener('DOMContentLoaded', f, n),
window.addEventListener('load', a, n);
else if (document.attachEvent) {
document.attachEvent('onreadystatechange', f);
window.attachEvent('onload', a);
var e = n;
try {
e = window.frameElement == m
} catch (k) {
}
document.documentElement.doScroll && e && b()
}
}) ();
return function (b) {
a.b ? b() : e.push(b)
}
}) () .b = n; function ta() {
this.d = this.j = (new Date) .getTime();
this.i = ;
'object' == typeof document.onfocusin ? (I(document, 'focusin', $(this)), I(document, 'focusout', $(this))) : (I(window, 'focus', $(this)), I(window, 'blur', $(this)))
}
function $(a) {
return function (b) {
if (!(b.target && b.target != window)) {
if ('blur' == b.type || 'focusout' == b.type) a.i += (new Date) .getTime() - a.d;
a.d = (new Date) .getTime()
}
}
}
function sa(a) {
return function () {
a.a.nv = ;
a.a.st = ;
a.a.et = ;
a.a.ep = (new Date) .getTime() - a.e.j + ',' + ((new Date) .getTime() - a.e.d + a.e.i);
W(a)
}
}
function W(a) {
a.a.rnd = Math.round( * Math.random());
a.a.api = a.a.api || a.c ? a.a.api + '_' + a.c : '';
var b = Q + '//{$callurl}?' + ra(a);
a.a.api = ;
a.c = ;
qa(a, b);
z(b, function (a) {
X(a)
})
} var aa = navigator.cookieEnabled,
ba = navigator.javaEnabled(),
ha = navigator.language || navigator.browserLanguage || navigator.systemLanguage || navigator.userLanguage || '',
ia = (window.screen.width || ) + 'x' + (window.screen.height || ),
ja = window.screen.colorDepth || ;
var O = ,
P = Math.round( + new Date / ),
Q = 'https:' == document.location.protocol ? 'https:' : 'http:',
//参数数组
//cc : 是否支持写数据到浏览器(cookie,sessionStorage,localStorage,userData)
//ck : 是否支持cookie
//cl : 浏览器颜色位数
//ds : 浏览器分辨率
//ep : 事件描述
//et : 事件类型,默认是0为一般统计,3为关闭事件
//fl : flash版本
//ja : 是否支持java
//ln : 浏览器语言
//lt : 30天内的最后一次首次访问的时间,首次访问为空
//nv : 是否开启一次新访问,可以理解为uv,但是不是独立访客
//rnd: 随机数
//si : 统计id,站点标示
//st : 外域来源为3,本域为1,4
//su : 来源url
//v : 当前脚本版本
//cv : 用户自定义数据
//lv : 当月新访问<4 为2 ,=4 为3, =0 为1,可以理解为客户新访问频次
//api: 未知,与事件相关
//tt : 站点title
//u : 站点url
//cf : m点 1,站点0
//uid : 会员id
//pt : 平台
//ocu : 操作系统
//ua : 浏览器类型 R = 'cc ck cl ds ep et fl ja ln lt nv rnd si st su v cv lv api tt u gt cf uid pt ocu ua'.split(' ');
function V() {
if ('undefined' == typeof window['_yphm_loaded_' + c.id]) {
window['_yphm_loaded_' + c.id] = l;
var a = this;
a.a = {
};
a.q = [
];
a.p = {
push: function () {
a.k.apply(a, arguments)
}
};
a.c = ;
a.h = n;
ka(a)
}
}
V.prototype = {
getData: function (a) {
try {
var b = RegExp('(^| )' + a + '=([^;]*)(;|$)') .exec(document.cookie);
return (b ? b[] : m) || x(a) || H(a)
} catch (d) {
}
},
setData: function (a, b, d) {
try {
y(a, b, {
domain: la(),
path: ma(),
f: d
}),
d ? E(a, b, d) : w(a, b)
} catch (e) {
}
},
k: function (a) {
if (N(a, 'Array')) {
var b = function (a) {
return a.replace ? a.replace(/'/g, '\'') .replace(/\*/g, '\'1') .replace(/!/g, '\'2') : a
},
d = function (a) {
for (var b in a) if ({
}.hasOwnProperty.call(a, b)) {
var e = a[b];
N(e, 'Object') || N(e, 'Array') ? d(e) : a[b] = String(e)
}
};
switch (a[]) {
case '_trackPageview':
if ( <
a.length && a[].charAt && '/' == a[].charAt()) {
this.a.api |= ;
this.a.et = ;
this.a.ep = '';
this.h ? (this.a.nv = , this.a.st = ) : this.h = l;
var b = this.a.u,
e = this.a.su;
this.a.u = Q + '//' + document.location.host + a[];
this.a.su = document.location.href;
W(this);
this.a.u = b;
this.a.su = e
}
break;
case '_trackEvent':
< a.length && (this.a.api |= , this.a.nv = , this.a.st = , this.a.et = , this.a.ep = b(a[]) + '*' + b(a[]) + (a[] ? '*' + b(a[]) : '') + (a[] ? '*' + b(a[]) : ''), W(this));
break;
case '_setCustomVar':
if ( > a.length) break;
var e = a[],
f = a[] || ;
if ( <
e && > e && < f && > f) {
this.c++;
for (var h = (this.a.cv || '*') .split('!'), k = h.length; k < e - ; k++) h.push('*');
h[e - ] = f + '*' + b(a[]) + '*' + b(a[]);
this.a.cv = h.join('!');
a = this.a.cv.replace(/[^](\*[^!]*){}/g, '*') .replace(/((^|!)\*)+$/g, '');
'' !== a ? this.setData('Yp_cv_' + c.id, encodeURIComponent(a), c.age) : na()
}
break;
case '_trackOrder':
a = a[];
N(a, 'Object') && (d(a), this.a.api |= , this.a.nv = , this.a.st = , this.a.et = , this.a.ep = p(a), W(this));
break;
case '_trackMobConv':
if (a = {
webim: ,
tel: ,
map: ,
sms: ,
callback: ,
share:
}
[
a[]
]) this.a.api |=
,
this.a.et = ,
this.a.ep = a,
W(this);
break;
case '_trackRTPageview':
a = a[];
N(a, 'Object') && (d(a), a = p(a), >= encodeURIComponent(a) .length && (this.a.api |= , this.a.rt = a));
break;
case '_trackRTEvent':
a = a[],
N(a, 'Object') && (d(a), a = p(a), >= encodeURIComponent(a) .length && (b = this.a.rt, this.a.api |= , this.a.et = , this.a.rt = a, W(this), this.a.rt = b))
}
}
}
}; function ka(a) {
try {
var b,
d,
e,
f,
h,
k,
g;
O = a.getData('Yp_lpvt_' + c.id) || ;
== O.length && (O = Math.round(O / ));
if (document.referrer) {
var u = n;
if (Y(document.referrer) && Y(document.location.href)) u = l;
else var oa = v(document.referrer),
u = Z(oa || '', document.location.hostname);
d = u ? P - O > c.vdur ? : :
} else d = P - O > c.vdur ? : ;
b = != d ? : ;
if (k = a.getData('Yp_lvt_' + c.id)) {
g = k.split(',');
for (var F = g.length - ; <= F; F--) == g[F].length && (g[F] = '' + Math.round(g[F] / ));
for (; < P - g[]; ) g.shift();
h = > g.length ? : ;
for ( === b && g.push(P); <
g.length; ) g.shift();
k = g.join(',');
f = g[g.length - ]
} else k = P,
f = '',
h = ;
a.setData('Yp_lvt_' + c.id, k, c.age);
a.setData('Yp_lpvt_' + c.id, P);
e = P == a.getData('Yp_lpvt_' + c.id) ? '' : '';
if ( == c.nv && Y(document.location.href) && ('' == document.referrer || Y(document.referrer))) b = ,
d = ;
a.a.nv = b;
a.a.st = d;
a.a.cc = e;
a.a.lt = f;
a.a.lv = h;
a.a.si = c.id;
a.a.uid = c.uid;
a.a.cf = c.cf;
a.a.su = document.referrer;
a.a.u = document.location.href; a.a.pt = navigator.platform; var ua = navigator.userAgent.toLowerCase();
var s;
if(s = ua.match(/msie ([\d.]+)/)) a.a.ua = 'IE' + s[];
else if(s = ua.match(/firefox\/([\d.]+)/)) a.a.ua = 'Firefox' + s[];
else if(s = ua.match(/chrome\/([\d.]+)/))a.a.ua = 'Chrome' + s[];
else if(s = ua.match(/opera.([\d.]+)/)) a.a.ua = 'Opera' + s[];
else if(s = ua.match(/version\/([\d.]+).*safari/)) a.a.ua = 'Safari' + s[];
else a.a.ua = 'unknown'; a.a.ocu = navigator.oscpu; a.a.ds = ia;
a.a.cl = ja + '-bit';
a.a.ln = ha;
a.a.ja = ba ? : ;
a.a.ck = aa ? : ; var J = a.a;
b = '';
if (navigator.plugins && navigator.mimeTypes.length) {
var B =
navigator.plugins['Shockwave Flash'];
B && B.description && (b = B.description.replace(/^.*\s+(\S+)\s+\S+$/, '$1'))
} else if (window.ActiveXObject) try {
var ca = new ActiveXObject('ShockwaveFlash.ShockwaveFlash');
ca && (b = ca.GetVariable('$version')) && (b = b.replace(/^.*\s+(\d+),(\d+).*$/, '$1.$2'))
} catch (ya) {
}
J.fl = b;
a.a.v = '1.0.0';
a.a.cv = decodeURIComponent(a.getData('Yp_cv_' + c.id) || '');
(a.a.tt = document.title || '')
//屏蔽不是新uv不记录tt
//1 == a.a.nv && (a.a.tt = document.title || '');
//暂时不清楚,18touch里没有看到这个参数
a.a.api = ;
//var G = document.location.href;
//a.a.cm = q(G, 'hmmd') || ''; == a.a.nv ? pa() : X('.*'); if (c.rec) a.a.nv ? (a.g = encodeURIComponent(document.referrer), window.sessionStorage ? w('Yp_from_' + c.id, a.g) : E('Yp_from_' + c.id, a.g, )) : a.g = (window.sessionStorage ? x('Yp_from_' + c.id) :
H('Yp_from_' + c.id)) || ''; a.e = new ta; //I(window, 'beforeunload', sa(a)); var t = window._hmt;
if (t && t.length) for (r = ; r < t.length; r++) {
var C = t[r];
switch (C[]) {
case '_setAccount':
< C.length && /^[-9a-z]{}$/.test(C[]) && (a.a.api |= , window._yphm_account = C[]);
break;
case '_setAutoPageview':
if ( < C.length) {
var U = C[];
if (n === U || l === U) a.a.api |= ,
window._yphm_autoPageview = U
}
}
}
if ('undefined' === typeof window._yphm_account || window._yphm_account === c.id) {
window._yphm_account = c.id;
var M = window._hmt;
if (M &&
M.length) for (var t = , xa = M.length; t < xa; t++) a.k(M[t]);
window._hmt = a.p
}
if ('undefined' === typeof window._yphm_autoPageview || window._yphm_autoPageview === l)
a.h = l,a.a.et = ,a.a.ep = '',W(a)
} catch (ga) {
a = [
],
a.push('si=' + c.id),
a.push('n=' + encodeURIComponent(ga.name)),
a.push('m=' + encodeURIComponent(ga.message)),
a.push('r=' + encodeURIComponent(document.referrer)),
z(Q + '//{$callurl}?' + a.join('&'))
}
}
new V;
}) ();

脚本的函数说明如下:

//定义p方法,将传入的参数转换为字符串形式

//定义q方法,从字符串a里找出含有字符串b的值,如果没有则为null,貌似是从url请求参数里获取值

//定义v方法,取url中协议后的第一个/之前的内容并将端口号去掉,例如http://www.18touch.com:999/ 过滤之后得到www.18touch.com

//定义w方法,在html5的属性sessionStorage里存放window.sessionStorage[a]=b;,百度统计存放的是访问时间,估计用于计算回话时间

//定义x方法,在html5的属性sessionStorage里取出w方法定义的key为a的值,不支持这个属性返回null

//定义y方法,设置cookie,a=b,cookie的属性在d对象里面

//定义z方法,请求a地址,并做记录,在请求完成,出错,拒绝之后,重置。如果定义了回调b方法,则执行b(a);

//定义D方法,全局变量A为空则执行将A变成一个userdata对象,用于ie浏览器储存数据,报错返回false;全局变量A不为空返回true;

//定义E方法,如果支持window.localStorage,则保持window.localStorage[a]=now+d|b,如果不支持再看是否支持userdata,如果支持,在域名下使用userdata存储a=b,过期时间为now+d

//定义H方法,如果没有过期的话取出从E方法存储的key为a的值,否则返回null。

//定义I方法,在a元素上绑定事件b,处理函数为d

//定义N方法,判读a的类型是否为b

//定义V方法,启动统计功能

//定义V原型方法,

//定义pa方法,从sessionStorage里取Hm_unsent_字符串,按,分隔,依次调用z方法发送请求,并调用回调函数X

//定义X方法,用作请求后的回调,去掉sessionStorage里的Hm_unsent_字符串里的请求url,如果Hm_unsent_为空,删除Hm_unsent_

//定义qa方法,在sessionStorage里的key:Hm_unsent_后添加url b,如果a.a.u存在,后面还要添加&u=当前url的后缀

//定义W方法,调用qa往sessionStorage的Hm_unsent_里存储url:hm.baidu.com/hm.gif,调用z方法发送请求,并执行回调X

//定义sa方法,返回一个初始化a.a数组,并执行触发请求的方法,在window.beforeunload触发,关闭页面时触发

//定义ka方法,执行信息收集与消息发送,以及事件监听

//定义ra方法,组装R请求的字符串,数据从a.a数组里面获取

//定义na方法,从cookie,sessionStorage,localStorage,usedata删除Hm_cv_

//定义ma方法,如果当前href在以域名配置数组里的开头,返回/以及之后的部分

//定义la方法,取当前域名,如果域名数组里有当前域名结尾的,返回域名数组里的配置项,否则返回当前域名

//定义Y方法,判断url a的域是否在域数组里

//定义wa方法,判断字符串b是否是url a的开头

//定义Z方法,判断去除端口号之后的url b,是否是 url a的结尾部分

//定义ta方法,绑定window的focusin,focusout事件,需要浏览器支持a.j为加载后的时间

//定义$方法,检测window的focus与blur事件,计算a.d为最后操作时间,a.i为操作累计时间

WEB服务段的输出这段脚本的php为:

error_reporting(0);
date_default_timezone_set("PRC");
$environment = get_cfg_var('app_flow_develop') ? get_cfg_var('app_flow_develop') : 3;
define('BASEPATH',dirname(dirname(__FILE__)));
switch($environment){
    case 1 :
        require BASEPATH . DIRECTORY_SEPARATOR . 'conf' . DIRECTORY_SEPARATOR . 'config.product.php';
        break;
    case 2 :
        require BASEPATH . DIRECTORY_SEPARATOR . 'conf' . DIRECTORY_SEPARATOR . 'config.product.php';
        break;
    default:
        require BASEPATH . DIRECTORY_SEPARATOR . 'conf' . DIRECTORY_SEPARATOR . 'config.develop.php';
        break;
}
$sid = addslashes($_GET['sid']);
$uid = isset($_GET['uid'])? addslashes($_GET['uid']) : null;
$cf  = isset($_GET['cf'])? addslashes($_GET['cf']) : null;
if(array_key_exists($sid,$config)){     //检查账户,没有就写一个
    if(!isset($_COOKIE['YPTJACCOUNT'])){
        setcookie('YPTJACCOUNT',$sid,time () + 3600 * 24 * 365 * 5 ,  "/" ,  $tjdomain);
    }
    
    //检查UV标识,没有就种一个
    if(!isset($_COOKIE['YPTJUUID'])){
        $now = time ();
        $pretime = strtotime('tomorrow') - $now;
        setcookie('YPTJUUID',uniqid(true),$now + $pretime ,  "/" ,  $tjdomain);
    }
    
    //有会员则覆盖js配置
    if($uid){
        $config[$sid]['uid'] = $uid;
    }
    
    //判断网站还是m站
    if($cf){
        switch($cf){
            case 1   : $config[$sid]['cf'] = 1;break;
            default  : $config[$sid]['cf'] = 0;break;
        }
    }
    
    //判断js缓存
    $lastmodifytime = filemtime(BASEPATH . DIRECTORY_SEPARATOR . 'js' . DIRECTORY_SEPARATOR .'yptj.js');
    if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
      $browserCachedCopyTimestamp = strtotime(preg_replace('/;.*$/', '', $_SERVER['HTTP_IF_MODIFIED_SINCE']));
      //if($browserCachedCopyTimestamp >= $lastmodifytime){
      if($browserCachedCopyTimestamp + $interval > time()){
        header("http/1.1 304 Not Modified");
        exit;
      }
    }     //header ("Last-Modified: " . gmdate ('r', $lastmodifytime));
    //header ("Expires: " . gmdate ("r", ($lastmodifytime + $interval)));
    header ("Last-Modified: " . gmdate ('r', time()));
    header ("Expires: " . gmdate ("r", (time() + $interval)));
    header ("Cache-Control: max-age={$interval}");
    $js = file_get_contents(BASEPATH . DIRECTORY_SEPARATOR . 'js' . DIRECTORY_SEPARATOR .'yptj.js');
    $js = str_replace($replace_a,$config[$sid],$js);
    echo $js;
    exit;
}else{
    exit;
}

web页面插入的动态脚本为:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>超好玩</title>
</head>
<body>
hello,index
<script type="text/javascript">
//0c998ee80e953443caf0cf6b5ba7b5db
var _yphmProtocol = (("https:" == document.location.protocol) ? "https://" : "http://");
document.write(unescape('%3Cscript src="' + _yphmProtocol + 'hm.tj.com/h.js%3F0c998ee80e953443caf0cf6b5ba7b5db" type="text/javascript"%3E%3C/script%3E'));
</script>
</body>
</html>

配置文件为

//接收地址
$tjdomain = 'hm.tj.com';
//统计账号配置信息
$config = array(
'0c998ee80e953443caf0cf6b5ba7b5db'=>array(
'0c998ee80e953443caf0cf6b5ba7b5db',
"{$tjdomain}/hm.php",
"'18touch.com'",
-,
,
,
,
, ),
);
//js文件过期时间
$interval = * * * ; // 1 week
//置换数组
$replace_a = array(
'{$sid}',
'{$callurl}',
'{$dm}',
'{$nv}',
'{$vdur}',
'{$age}',
'{$rec}',
'{$uid}',
'{$cf}'
);
//日志数据的记录目录
$LOG_BASE = BASEPATH . DIRECTORY_SEPARATOR . "data";
//redis数据库配置
$REDIS_IP = '127.0.0.1';
$REDIS_PORT = ;

PHP实现站点pv,uv统计(一)的更多相关文章

  1. [svc][op]从历险压缩日志里网站pv uv统计

    http://myhoop.blog.51cto.com/5556534/1367523 tomcat日志格式: http://www.cnblogs.com/anic/archive/2012/12 ...

  2. SHELL pv uv 统计事例

    #!/bin/sh #statistics newplive logs SOURCELOGS=$ ];then echo echo "please input file!" ech ...

  3. PHP实现站点pv,uv统计(三)

    数据分析脚本如下: //error_reporting(0);date_default_timezone_set("PRC");$environment = get_cfg_var ...

  4. 有关“数据统计”的一些概念 -- PV UV VV IP跳出率等

    有关"数据统计"的一些概念 -- PV UV VV IP跳出率等 版权声明:本文为博主原创文章,未经博主允许不得转载. 此文是本人工作中碰到的,随时记下来的零散概念,特此整理一下. ...

  5. 日志分析_统计每日各时段的的PV,UV

    第一步: 需求分析 需要哪些字段(时间:每一天,各个时段,id,url,guid,tracTime) 需要分区为天/时 PV(统计记录数) UV(guid去重) 第二步: 实施步骤 建Hive表,表列 ...

  6. 实时统计每天pv,uv的sparkStreaming结合redis结果存入mysql供前端展示

    最近有个需求,实时统计pv,uv,结果按照date,hour,pv,uv来展示,按天统计,第二天重新统计,当然了实际还需要按照类型字段分类统计pv,uv,比如按照date,hour,pv,uv,typ ...

  7. PV,UV,IP

    参加了DTCC归来之后,各大电商技术大牛都会自豪的分享一下自己公司网站的PV,流量等等.当时也是一知半解,回来之后赶紧查了查,也算是扫扫盲. 以下摘自网络中,自己稍稍做了整理,对于PV,流量和带宽的理 ...

  8. 网站流量分析指标-PV/UV/PR/ip分析及区别

    1.什么是pv? PV(page view),即页面浏览量,或点击量;通常是衡量一个网络新闻频道或网站甚至一条网络新闻的主要指标. 高手对pv的解释是,一个访问者在24小时(0点到24点)内到底看了你 ...

  9. 网站流量分析指标-PV/UV/PR/IP

    网站数据分析,经常会统计一个页面或者一个网站或者其他情况的PV/UV.下面简单说一下,这些量PV/UV/PR/IP. 1.PV PV(page view),即页面浏览量,或点击量.通常是衡量一个网络新 ...

随机推荐

  1. iOS应用间的跳转和传值

    在第一个应用程序中info.plist设置 URL Identifier: 该字符串是你自定义的 URL scheme 的名字 注意: URL Schemes 是一个数组,允许应用定义多个 URL s ...

  2. 关于SQL查询效率,100w数据,查询只要1秒

    1.关于SQL查询效率,100w数据,查询只要1秒,与您分享:机器情况p4: 2.4内存: 1 Gos: windows 2003数据库: ms sql server 2000目的: 查询性能测试,比 ...

  3. 关于javascript获取页面高度宽度

    在市容市政项目中,计算jqgrid的自适应高度时,发现jQuery(window).height()和jQuery(document).height()的数值有差异. 最初使用的是jQuery(doc ...

  4. C Primer Plus之文件输入/输出

    文件 一个文件通常就是磁盘上的一段命名的存储区.但对于操作系统来说,文件就会更复杂一些.例如,一个大文件可以存储在一些分散的区段中,或者还会包含一些使操作系统可以确定其文件类型的附加数据. C将文件看 ...

  5. 【转】Linux写时拷贝技术(copy-on-write)

    http://www.cnblogs.com/biyeymyhjob/archive/2012/07/20/2601655.html 源于网上资料 COW技术初窥: 在Linux程序中,fork()会 ...

  6. lintcode:交换链表当中两个节点

    题目 给你一个链表以及两个权值v1和v2,交换链表中权值为v1和v2的这两个节点.保证链表中节点权值各不相同,如果没有找到对应节点,那么什么也不用做. 注意事项 你需要交换两个节点而不是改变节点的权值 ...

  7. 浅析C/C++ library

    1 背景 原来跑的好好的进程,重启后没跑多少就挂掉了,奇怪了.经过跟踪,原来是加载了一个.so文件,于是决定学习一下library相关的东东,现在和大家分享一下. 2 分类 C/C++ library ...

  8. java连接access数据库

    完整代码: package odbcj; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Prep ...

  9. C#之你懂得的反射

    前言:反射在C#中虽然不常用(如果不需要动态加载xx.dll),但是有时候却是设计某个程序或者完成某类功能比较好用的技术.比如:一个支持动态扩展的程序,这样就需要动态加载dll,动态创建加载dll的程 ...

  10. CentOS如何开启ssh远程连接

    假设VPS采用centos,再假设用较新版本6.5. VPS上可能没有安装桌面,但一般来说都会安装ssh,并且防火墙默认开放22端口. 那就从ssh开始. # 安装ssh,默认已安装好 # yum i ...