辛夷坞

涧户寂无人,纷纷开且落

By - Christen

广告监测分析案例

广告素材:Here
跳转链接:Here
分析环境
操作系统:OS X Mavericks
浏览器:Google Chrome 版本 31.0.1650.48

先查一下监测公司的来历
打开万网,查询监测域名mlt01,查看 mlt01.com 的信息:
http://whois.www.net.cn/whois/domain/mlt01.com
注册商
Sponsoring Registrar 北京万网志成科技有限公司
注册日期
Registration Date(EDT) 28-nov-2011
展开 查看完整注册信息,能找到以下资料:

Registrant ID ................... hc177366686-cn
Registrant Name ................. Wang Cain
Registrant Organization ......... Menlo Technology Co, Ltd.
Registrant Address .............. Room 1, Building 1, No.333 HongQiao Road
Registrant City ................. shang hai shi
Registrant Province/State ....... shang hai
Registrant Postal Code .......... 200000
Registrant Country Code ......... CN
Registrant Phone Number ......... +86.02162675588
Registrant Fax .................. +86.02162675588
Registrant Email ................ cain.wang@menlotechnologies.cn

Google Menlo Technology Co,就能找到公司信息:
http://www.adchina.com/en/us/Menlo.aspx
易传媒,我们的老朋友了!
注册人为易传媒解决方案副总裁@王华CainWang
易传媒的两篇介绍文档:
http://www.docin.com/p-278696126.html
http://www.docin.com/p-462701156.html
常规监测分为三类:
1、流量监测
+ + I 打开 Chrome 控制台,激活流量面板,访问素材地址,可看到以下网络请求:

http://mlt01.com/o.htm?pv=0&sp=0,858396,872117,88763,0,1,1

这是易传媒的流量监测,很常规的请求,写 Cookie,记 Referer,User-Agent,还传了两个我们看不懂的参数。

Date:Wed, 20 Nov 2013 04:23:58 GMT
Expires:Mon, 1 Jan 1970 00:00:00 GMT
P3P:CP="NOI CURa ADMa DEVa OUR IND UNI COM NAV INT"
Server:nginx
Set-Cookie:CITY=900:255,-1:255,; domain=.mlt01.com; expires=Thu, 20-Nov-2014 04:23:58 GMT; path=/
Set-Cookie:cpcap=; path=/
Set-Cookie:lv5w8bs=; expires=Tue, 19-Nov-2013 04:23:58 GMT; path=/
Set-Cookie:categoryid=; path=/
Set-Cookie:mbcap=; path=/
Set-Cookie:CSV=; domain=.mlt01.com; expires=Fri, 20-Nov-2043 04:23:58 GMT; path=/
X-Powered-By:UrlRewriter.NET 2.0.0

2、点击监测
点击监测有三个参数:

pv     = 1
sp     = 0,858396,872117,88763,0,1,1
target = http://lefen.lenovo.com/index.php/pph/see/42

对比之前的流量监测,我们会有以下结论:
易传媒用 o.htm 处理流量请求,用 c.htm 处理点击请求,记住这些规则,能有效防止错把点击加成了流量之类的事故。
流量的 sp 参数和点击的 sp 参数完全一致,这给他们后期做点击和流量的一致性分析,提供了数据基础。如果某个IP只做了点击,而没有对应的曝光,很容易被纠出来。
target 表示跳转目标,到联想的乐份俱乐部,这个由某标负责的项目,页面水平直追当代大学生的毕业设计稿,URL Rewrite 都做得这么业余,怀疑有过二次转包。
点击监测同样会记录 Referer, 写 Cookie:

Date:Wed, 20 Nov 2013 05:01:57 GMT
Expires:Mon, 1 Jan 1970 00:00:00 GMT
Location:http://lefen.lenovo.com/index.php/pph/see/42
P3P:CP="NOI CURa ADMa DEVa OUR IND UNI COM NAV INT"
Server:nginx
Set-Cookie:clk=84704:0,84483:0,82730:0,84445:0,84918:8,; expires=Fri, 20-Nov-2043 05:01:57 GMT; path=/
Via:HTTP/1.1 GWA

3、页面监测
页面上没有添加联想自己的监测,但理论上这种动态项目,最后一道防线,就是系统日志了,这些暂不考虑。
重点专注第三方监测
查看页面源代码,发现有两家:
1)、百度统计

<script type="text/javascript">
var _bdhmProtocol = (("https:" == document.location.protocol) ? " https://" : " http://");
document.write(unescape("%3Cscript src='" + _bdhmProtocol + "hm.baidu.com/h.js%3Ffe5c1502be9adcdabd9978e353b291a1' type='text/javascript'%3E%3C/script%3E"));
</script>

网络面板的请求非常多,可以过滤一下请求,激活网络面板,按 + F,输入 baidu,勾选 Filter,就可以很方便的查看百度请求了。

百度统计为全方位监测,可通过 Request HeadersQuery String ParametersResponse Header 查看详细信息。
2)、易传媒

<!-- PV监测代码 -->
<script type="text/javascript">
	MltTracker= {
	mid: 250051, //获取mediabuyid
	ers: [{ "type": "pageview",uid: "",pid:"" }],
	track: function (er)
	{
		this.ers.push(er);
	}};
	(function ()
	{
		var js = document.createElement("script"), scri = document.getElementsByTagName("script")[0];
		js.type = "text/javascript";
		js.async = true;
		scri.parentNode.insertBefore(js, scri);
		js.src = location.protocol == "https:" ? "https://secure.mlt01.com/nt.js" : "http://static.mlt01.com/nt.js";
	})();
</script>

做页面的同学,非常体贴,专门做了注释。
相对百度,易传媒的监测更加细致:

Query String Parameters
rct:html
g:0
mid:250051
u:1,11
sr:1280,800
dt:联想智能手机|乐粉俱乐部|品牌汇
src:5
ssn:16902307135873180,1,1384922155,1,1384922155
jsv:4
type:pageview

甚至取了页面标题 dt,有效了堵住了某些直接刷监测代码优化数据的渠道。
附录:
易传媒的监测代码

function(a) {
    if ("undefined" == typeof _MltTracker) {
        _MltTracker = null;
        var d, b = 15552e6,
        c = 2592e6,
        e = _MltTracker = function(a) {
            return new e.prototype.init(a)
        };
        e.extend = function(a, b) {
            var c;
            for (c in b) b.hasOwnProperty(c) && (a = b);
            return a
        },
        e.extend(e, {
            idle: [1, 1],
            getProtocol: function() {
                return "https:" === location.protocol ? "https://": "http://"
            },
            joinParameters: function(b, c) {
                var e, d = [];
                if ("," === c) for (e in b) b.hasOwnProperty(e) && "" !== b[e] && b[e] != a && Array.prototype.push.call(d, b[e]);
                else if ("&" === c) for (e in b) b.hasOwnProperty(e) && "" !== b[e] && b[e] != a && Array.prototype.push.call(d, e + "=" + b[e]);
                return d.join(c)
            },
            getCurrentUrl: function() {
                var b = "";
                try {
                    b = top.location.href
                } catch(c) {
                    b = location.href
                }
                return encodeURIComponent(b)
            },
            getPreviousUrl: function() {
                var a = "";
                try {
                    a = top.document.referrer
                } catch(b) {
                    try {
                        a = document.referrer
                    } catch(c) {}
                }
                return encodeURIComponent(a)
            },
            getQueryString: function(a) {
                var b, c, f, g, h, d = {};
                if (!e.queryString) {
                    try {
                        b = top.location.search
                    } catch(i) {
                        b = location.search
                    }
                    if (b) for (b = b.substr(1), c = b.split("&"), f = 0, g = c.length; g > f; f++) h = c[f].split("="),
                    2 === h.length && (d[h[0]] = h[1]);
                    e.queryString = d
                }
                return e.queryString[a]
            },
            getCookieEnabled: function() {
                return navigator.cookieEnabled ? 1 : 0
            },
            getFlashVersion: function() {
                var a = "0,0,0,0";
                try {
                    navigator.plugins && navigator.plugins["Shockwave Flash"] ? a = navigator.plugins["Shockwave Flash"].description: window.ActiveXObject && new ActiveXObject("ShockwaveFlash.ShockwaveFlash") && (a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable("$version"))
                } catch(b) {}
                return a = a.match(/d+/g),
                a[0]
            },
            load: function(a, b, c, d, e) {
                var f, i, g = /loaded|complete/i,
                h = "_script_$" + Math.ceil(1e10 * Math.random());
                b ? (f = document.createElement("script"), f.type = "text/javascript", f.async = !0, f.charset = "utf-8", f.id = h, i = document.getElementsByTagName("script")[0], i.parentNode.insertBefore(f, i), f.src = a) : (window.ActiveXObject && (g = /complete/i), document.write('<script type="text/javascript" charset="utf-8" src="' + a + '" id="' + h + '"></scri' + "pt>")),
                f = document.getElementById(h),
                f && (f.onload = f.onreadystatechange = function() { (!f.readyState || f.readyState.match(g)) && ("function" == typeof c && c(), c = null, e = null, f && f.parentNode && (f.onload = f.onreadystatechange = null, f = null))
                }),
                d && setTimeout(function() {
                    f && ("function" == typeof e && e(), e = null, d = null, f.src = "javascript:void(0)")
                },
                d)
            },
            getTopDomain: function(a) {
                if (!arguments.callee.domain) {
                    for (var b = a || location.hostname,
                    c = b.split("."), d = /com|edu|gov|int|mil|net|org|biz|info|pro|name|museum|coop|aero|xxx|idv/, e = c.length - 1, f = 0; e > -1; e--) if (d.test(c[e])) {
                        f = e;
                        break
                    }
                    f = 0 === f ? 1 : f,
                    arguments.callee.domain = c.slice(f - 1).join(".")
                }
                return arguments.callee.domain
            },
            cookie: function(a, b, c) {
                if ("undefined" == typeof b) {
                    var e = ";?" + a + "=([^;]*);?",
                    f = new RegExp(e);
                    return f.test(document.cookie) ? RegExp.$1: null
                }
                null === b && (b = "", c = c || {},
                c.expires = -1);
                var d = a + "=" + b;
                c && (c.path && (d += "; path=" + c.path), c.expires instanceof Date && (d += "; expires=" + c.expires.toGMTString()), c.domain && (d += "; domain=" + c.domain), c.secure && (d += "; secure")),
                document.cookie = d
            },
            fc: function() {}
        }),
        e.prototype = {
            constructor: "_MltTracker",
            jsv: 4,
            init: function(a) {
                if (a.mid) {
                    var f, g, h, i, c = this;
                    for (c.mid = a.mid, a.ecc && (c.ecc = a.ecc), h = c.zcookie("mltn"), i = c.zcookie("mlts"), d = "." + e.getTopDomain(), (d.lastIndexOf(".") < 1 || !/w/.test(d)) && (d = null), h || c.zcookie("mltn", [0, 0, 0, 0, 0].join(">"), {
                        domain: d,
                        expires: new Date((new Date).getTime() + b),
                        path: "/"
                    }), a.serverbaseurl && (c.serverbaseurl = a.serverbaseurl), f = 0, g = a.ers.length; g > f; f++) c.track(a.ers[f])
                }
            },
            zcookie: function(a, b, c) {
                var d = this,
                f = d.mid,
                g = new RegExp("@" + f + "~([^@]+)+@"),
                h = e.cookie(a);
                return "undefined" == typeof b ? h && g.test(h) ? RegExp.$1: null: (b = h ? g.test(h) ? h.replace(g, "@" + f + "~" + b + "@") : h + "@" + f + "~" + b + "@": "@" + f + "~" + b + "@", e.cookie(a, b, c), void 0)
            },
            track: function(a) {
                var b = this; !
                function() {
                    if (e.idle[1]) {
                        var c = b.getServerUrl() + b.getParameters(a);
                        e.idle[1] = 0,
                        b.cer = a,
                        e.load(c, 1,
                        function() {
                            e.idle[1] = 1
                        })
                    } else setTimeout(arguments.callee, 0)
                } ()
            },
            generateCurrentUrl: function(a) {
                var b = "";
                try {
                    b = 0 == a.indexOf("/") ? top.location.protocol + "//" + top.location.host + a: /^https?:///.test(a) ? a: top.location.protocol + "//" + top.location.host + top.location.pathname.slice(0, top.location.pathname.lastIndexOf("/")) + "/" + a
                } catch(c) {
                    b = 0 == a.indexOf("/") ? location.protocol + "//" + location.host + a: /^https?:///.test(a) ? a: location.protocol + "//" + location.host + location.pathname.slice(0, location.pathname.lastIndexOf("/")) + "/" + a
                }
                return encodeURIComponent(b)
            },
            getParameters: function(b) {
                var d, h, j, l, c = this,
                f = {
                    rct: "html",
                    g: 0,
                    mid: c.mid,
                    u: [e.getCookieEnabled(), e.getFlashVersion()].join(","),
                    sr: [screen.width, screen.height].join(","),
                    dt: encodeURIComponent(document.title)
                },
                g = c.zcookie("mltis"),
                i = c.zcookie("mlts"),
                k = c.zcookie("mltn");
                if (g && (h = g.split(">"), f.aid = h[1], f.bid = h[2], f.cid = h[3]), i && (j = i.split(">"), f.src = j.join(",")), k && (l = k.split(">"), 0 != l[0] && (f.ssn = l.join(","))), c.ecc && (f.curl = encodeURIComponent(document.referrer)), b.path && "pageview" === b.type ? (f.purl = c._purl || e.getCurrentUrl(), f.curl = c.generateCurrentUrl(b.path), c._purl = f.curl, b.path = null) : f.purl = e.getPreviousUrl(), f.jsv = c.jsv, "object" == typeof b) for (d in b) b.hasOwnProperty(d) && "" !== b[d] && b[d] != a && (f[d] = encodeURIComponent(b[d]));
                return e.joinParameters(f, "&")
            },
            s: function(a, e, f, g, h, i, j) {
                var k = this;
                switch (a) {
                case 1:
                    k.zcookie("mltis", [a, e || 0, f || 0, g || 0].join(">"), {
                        domain: d,
                        expires: new Date((new Date).getTime() + c),
                        path: "/"
                    }),
                    k.zcookie("mlts", [a, encodeURIComponent(e || 0), encodeURIComponent(f || 0), encodeURIComponent(g || 0)].join(">"), {
                        domain: d,
                        expires: new Date((new Date).getTime() + b),
                        path: "/"
                    });
                    break;
                case 2:
                    k.zcookie("mlts", [a, encodeURIComponent(e || ""), encodeURIComponent(f || ""), encodeURIComponent(g || ""), encodeURIComponent(h || "")].join(">"), {
                        domain: d,
                        expires: new Date((new Date).getTime() + b),
                        path: "/"
                    });
                    break;
                case 3:
                    k.zcookie("mlts", [a, encodeURIComponent(e || ""), encodeURIComponent(f || "")].join(">"), {
                        domain: d,
                        expires: new Date((new Date).getTime() + b),
                        path: "/"
                    });
                    break;
                case 4:
                    k.zcookie("mlts", [a, encodeURIComponent(e || "")].join(">"), {
                        domain: d,
                        expires: new Date((new Date).getTime() + b),
                        path: "/"
                    });
                    break;
                case 5:
                    k.zcookie("mlts", [a].join(">"), {
                        domain: d,
                        expires: new Date((new Date).getTime() + b),
                        path: "/"
                    });
                    break;
                case 6:
                    k.zcookie("mltis", [a, e || 0, f || 0, g || 0].join(">"), {
                        domain: d,
                        expires: new Date((new Date).getTime() + c),
                        path: "/"
                    }),
                    k.zcookie("mlts", [a, encodeURIComponent(h || ""), encodeURIComponent(i || ""), encodeURIComponent(j || "")].join(">"), {
                        domain: d,
                        expires: new Date((new Date).getTime() + b),
                        path: "/"
                    })
                }
            },
            n: function(a, c) {
                var e = this,
                f = e.zcookie("mltn"),
                g = f.split(">");
                g[0] != a && (g[1] = 0, g[3] = 0),
                "pageview" === e.cer.type && (g[3] = parseInt(g[3], 10) + 1, g[4] = c),
                g[0] = a,
                g[1] = parseInt(g[1], 10) + 1,
                g[2] = c,
                e.zcookie("mltn", g.join(">"), {
                    domain: d,
                    expires: new Date((new Date).getTime() + b),
                    path: "/"
                })
            },
            getServerUrl: function() {
                var a = this;
                return e.getProtocol() + a.getBaseUrl() + "nt.htm?"
            },
            getBaseUrl: function() {
                var a = this;
                return a.serverbaseurl ? a.serverbaseurl: "https:" === location.protocol ? "secure.mlt01.com/": "mlt01.com/"
            }
        },
        e.prototype.init.prototype = e.prototype
    }
} (),
"undefined" != typeof MltTracker && "_MltTracker" !== MltTracker.constructor && (MltTracker = _MltTracker(MltTracker));

Leave a Reply

Your email address will not be published.
*
*