




已閱讀5頁(yè),還剩13頁(yè)未讀, 繼續(xù)免費(fèi)閱讀
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
網(wǎng)站統(tǒng)計(jì)中的數(shù)據(jù)收集原理及實(shí)現(xiàn)_埋點(diǎn)統(tǒng)計(jì)網(wǎng)站數(shù)據(jù)統(tǒng)計(jì)分析工具是網(wǎng)站站長(zhǎng)和運(yùn)營(yíng)人員經(jīng)常使用的一種工具,比較常用的有谷歌分析、百度統(tǒng)計(jì)和騰訊分析等等。所有這些統(tǒng)計(jì)分析工具的第一步都是網(wǎng)站訪問(wèn)數(shù)據(jù)的收集。目前主流的數(shù)據(jù)收集方式基本都是基于javascript的。本文將簡(jiǎn)要分析這種數(shù)據(jù)收集的原理,并一步一步實(shí)際搭建一個(gè)實(shí)際的數(shù)據(jù)收集系統(tǒng)。數(shù)據(jù)收集原理分析簡(jiǎn)單來(lái)說(shuō),網(wǎng)站統(tǒng)計(jì)分析工具需要收集到用戶瀏覽目標(biāo)網(wǎng)站的行為(如打開(kāi)某網(wǎng)頁(yè)、點(diǎn)擊某按鈕、將商品加入購(gòu)物車等)及行為附加數(shù)據(jù)(如某下單行為產(chǎn)生的訂單金額等)。早期的網(wǎng)站統(tǒng)計(jì)往往只收集一種用戶行為:頁(yè)面的打開(kāi)。而后用戶在頁(yè)面中的行為均無(wú)法收集。這種收集策略能滿足基本的流量分析、來(lái)源分析、內(nèi)容分析及訪客屬性等常用分析視角,但是,隨著ajax技術(shù)的廣泛使用及電子商務(wù)網(wǎng)站對(duì)于電子商務(wù)目標(biāo)的統(tǒng)計(jì)分析的需求越來(lái)越強(qiáng)烈,這種傳統(tǒng)的收集策略已經(jīng)顯得力不能及。后來(lái),Google在其產(chǎn)品谷歌分析中創(chuàng)新性的引入了可定制的數(shù)據(jù)收集腳本,用戶通過(guò)谷歌分析定義好的可擴(kuò)展接口,只需編寫少量的javascript代碼就可以實(shí)現(xiàn)自定義事件和自定義指標(biāo)的跟蹤和分析。目前百度統(tǒng)計(jì)、搜狗分析等產(chǎn)品均照搬了谷歌分析的模式。其實(shí)說(shuō)起來(lái)兩種數(shù)據(jù)收集模式的基本原理和流程是一致的,只是后一種通過(guò)javascript收集到了更多的信息。下面看一下現(xiàn)在各種網(wǎng)站統(tǒng)計(jì)工具的數(shù)據(jù)收集基本原理。流程概覽首先通過(guò)一幅圖總體看一下數(shù)據(jù)收集的基本流程。圖1. 網(wǎng)站統(tǒng)計(jì)數(shù)據(jù)收集基本流程首先,用戶的行為會(huì)觸發(fā)瀏覽器對(duì)被統(tǒng)計(jì)頁(yè)面的一個(gè)http請(qǐng)求,這里姑且先認(rèn)為行為就是打開(kāi)網(wǎng)頁(yè)。當(dāng)網(wǎng)頁(yè)被打開(kāi),頁(yè)面中的埋點(diǎn)javascript片段會(huì)被執(zhí)行,用過(guò)相關(guān)工具的朋友應(yīng)該知道,一般網(wǎng)站統(tǒng)計(jì)工具都會(huì)要求用戶在網(wǎng)頁(yè)中加入一小段javascript代碼,這個(gè)代碼片段一般會(huì)動(dòng)態(tài)創(chuàng)建一個(gè)script標(biāo)簽,并將src指向一個(gè)單獨(dú)的js文件,此時(shí)這個(gè)單獨(dú)的js文件(圖1中綠色節(jié)點(diǎn))會(huì)被瀏覽器請(qǐng)求到并執(zhí)行,這個(gè)js往往就是真正的數(shù)據(jù)收集腳本。數(shù)據(jù)收集完成后,js會(huì)請(qǐng)求一個(gè)后端的數(shù)據(jù)收集腳本(圖1中的backend),這個(gè)腳本一般是一個(gè)偽裝成圖片的動(dòng)態(tài)腳本程序,可能由php、python或其它服務(wù)端語(yǔ)言編寫,js會(huì)將收集到的數(shù)據(jù)通過(guò)http參數(shù)的方式傳遞給后端腳本,后端腳本解析參數(shù)并按固定格式記錄到訪問(wèn)日志,同時(shí)可能會(huì)在http響應(yīng)中給客戶端種植一些用于追蹤的cookie。上面是一個(gè)數(shù)據(jù)收集的大概流程,下面以谷歌分析為例,對(duì)每一個(gè)階段進(jìn)行一個(gè)相對(duì)詳細(xì)的分析。埋點(diǎn)腳本執(zhí)行階段若要使用谷歌分析(以下簡(jiǎn)稱GA),需要在頁(yè)面中插入一段它提供的javascript片段,這個(gè)片段往往被稱為埋點(diǎn)代碼。下面是我的博客中所放置的谷歌分析埋點(diǎn)代碼截圖:圖2. 谷歌分析埋點(diǎn)代碼其中_gaq是GA的的全局?jǐn)?shù)組,用于放置各種配置,其中每一條配置的格式為:_gaq.push(Action,param1,param2,.);Action指定配置動(dòng)作,后面是相關(guān)的參數(shù)列表。GA給的默認(rèn)埋點(diǎn)代碼會(huì)給出兩條預(yù)置配置,_setAccount用于設(shè)置網(wǎng)站標(biāo)識(shí)ID,這個(gè)標(biāo)識(shí)ID是在注冊(cè)GA時(shí)分配的。_trackPageview告訴GA跟蹤一次頁(yè)面訪問(wèn)。更多配置請(qǐng)參考:/analytics/devguides/collection/gajs/。實(shí)際上,這個(gè)_gaq是被當(dāng)做一個(gè)FIFO隊(duì)列來(lái)用的,配置代碼不必出現(xiàn)在埋點(diǎn)代碼之前,具體請(qǐng)參考上述鏈接的說(shuō)明。就本文來(lái)說(shuō),_gaq的機(jī)制不是重點(diǎn),重點(diǎn)是后面匿名函數(shù)的代碼,這才是埋點(diǎn)代碼真正要做的。這段代碼的主要目的就是引入一個(gè)外部的js文件(ga.js),方式是通過(guò)document.createElement方法創(chuàng)建一個(gè)script并根據(jù)協(xié)議(http或https)將src指向?qū)?yīng)的ga.js,最后將這個(gè)element插入頁(yè)面的dom樹(shù)上。注意ga.async = true的意思是異步調(diào)用外部js文件,即不阻塞瀏覽器的解析,待外部js下載完成后異步執(zhí)行。這個(gè)屬性是HTML5新引入的。數(shù)據(jù)收集腳本執(zhí)行階段數(shù)據(jù)收集腳本(ga.js)被請(qǐng)求后會(huì)被執(zhí)行,這個(gè)腳本一般要做如下幾件事:1、通過(guò)瀏覽器內(nèi)置javascript對(duì)象收集信息,如頁(yè)面title(通過(guò)document.title)、referrer(上一跳url,通過(guò)document.referrer)、用戶顯示器分辨率(通過(guò)windows.screen)、cookie信息(通過(guò)document.cookie)等等一些信息。2、解析_gaq收集配置信息。這里面可能會(huì)包括用戶自定義的事件跟蹤、業(yè)務(wù)數(shù)據(jù)(如電子商務(wù)網(wǎng)站的商品編號(hào)等)等。3、將上面兩步收集的數(shù)據(jù)按預(yù)定義格式解析并拼接。4、請(qǐng)求一個(gè)后端腳本,將信息放在http request參數(shù)中攜帶給后端腳本。這里唯一的問(wèn)題是步驟4,javascript請(qǐng)求后端腳本常用的方法是ajax,但是ajax是不能跨域請(qǐng)求的。這里ga.js在被統(tǒng)計(jì)網(wǎng)站的域內(nèi)執(zhí)行,而后端腳本在另外的域(GA的后端統(tǒng)計(jì)腳本是/_utm.gif),ajax行不通。一種通用的方法是js腳本創(chuàng)建一個(gè)Image對(duì)象,將Image對(duì)象的src屬性指向后端腳本并攜帶參數(shù),此時(shí)即實(shí)現(xiàn)了跨域請(qǐng)求后端。這也是后端腳本為什么通常偽裝成gif文件的原因。通過(guò)http抓包可以看到ga.js對(duì)_utm.gif的請(qǐng)求:圖3. 后端腳本請(qǐng)求的http包可以看到ga.js在請(qǐng)求_utm.gif時(shí)帶了很多信息,例如utmsr=12801024是屏幕分辨率,utmac=UA-35712773-1是_gaq中解析出的我的GA標(biāo)識(shí)ID等等。值得注意的是,_utm.gif未必只會(huì)在埋點(diǎn)代碼執(zhí)行時(shí)被請(qǐng)求,如果用_trackEvent配置了事件跟蹤,則在事件發(fā)生時(shí)也會(huì)請(qǐng)求這個(gè)腳本。由于ga.js經(jīng)過(guò)了壓縮和混淆,可讀性很差,我們就不分析了,具體后面實(shí)現(xiàn)階段我會(huì)實(shí)現(xiàn)一個(gè)功能類似的腳本。后端腳本執(zhí)行階段GA的_utm.gif是一個(gè)偽裝成gif的腳本。這種后端腳本一般要完成以下幾件事情:1、解析http請(qǐng)求參數(shù)的到信息。2、從服務(wù)器(WebServer)中獲取一些客戶端無(wú)法獲取的信息,如訪客ip等。3、將信息按格式寫入log。5、生成一副11的空gif圖片作為響應(yīng)內(nèi)容并將響應(yīng)頭的Content-type設(shè)為image/gif。5、在響應(yīng)頭中通過(guò)Set-cookie設(shè)置一些需要的cookie信息。之所以要設(shè)置cookie是因?yàn)槿绻櫸ㄒ辉L客,通常做法是如果在請(qǐng)求時(shí)發(fā)現(xiàn)客戶端沒(méi)有指定的跟蹤cookie,則根據(jù)規(guī)則生成一個(gè)全局唯一的cookie并種植給用戶,否則Set-cookie中放置獲取到的跟蹤cookie以保持同一用戶cookie不變(見(jiàn)圖4)。圖4. 通過(guò)cookie跟蹤唯一用戶的原理這種做法雖然不是完美的(例如用戶清掉cookie或更換瀏覽器會(huì)被認(rèn)為是兩個(gè)用戶),但是是目前被廣泛使用的手段。注意,如果沒(méi)有跨站跟蹤同一用戶的需求,可以通過(guò)js將cookie種植在被統(tǒng)計(jì)站點(diǎn)的域下(GA是這么做的),如果要全網(wǎng)統(tǒng)一定位,則通過(guò)后端腳本種植在服務(wù)端域下(我們待會(huì)的實(shí)現(xiàn)會(huì)這么做)。系統(tǒng)的設(shè)計(jì)實(shí)現(xiàn)根據(jù)上述原理,我自己搭建了一個(gè)訪問(wèn)日志收集系統(tǒng)??傮w來(lái)說(shuō),搭建這個(gè)系統(tǒng)要做如下的事:圖5. 訪問(wèn)數(shù)據(jù)收集系統(tǒng)工作分解下面詳述每一步的實(shí)現(xiàn)。我將這個(gè)系統(tǒng)叫做MyAnalytics。確定收集的信息為了簡(jiǎn)單起見(jiàn),我不打算實(shí)現(xiàn)GA的完整數(shù)據(jù)收集模型,而是收集以下信息。埋點(diǎn)代碼埋點(diǎn)代碼我將借鑒GA的模式,但是目前不會(huì)將配置對(duì)象作為一個(gè)FIFO隊(duì)列用。一個(gè)埋點(diǎn)代碼的模板如下: var_maq=_maq|; _maq.push(_setAccount,網(wǎng)站標(biāo)識(shí)); (function() varma=document.createElement(script);ma.type=text/javascript;ma.async=true; ma.src=(https:=tocol?https:/analytics:http:/analytics)+./ma.js; vars=document.getElementsByTagName(script)0;s.parentNode.insertBefore(ma,s); )(); 這里我啟用了二級(jí)域名,統(tǒng)計(jì)腳本的名稱為ma.js。當(dāng)然這里有一點(diǎn)小問(wèn)題,因?yàn)槲也](méi)有https的服務(wù)器,所以如果一個(gè)https站點(diǎn)部署了代碼會(huì)有問(wèn)題,不過(guò)這里我們先忽略吧。前端統(tǒng)計(jì)腳本我寫了一個(gè)不是很完善但能完成基本工作的統(tǒng)計(jì)腳本ma.js:(function() varparams=; /Document對(duì)象數(shù)據(jù) if(document) params.domain=document.domain|; params.url=document.URL|; params.title=document.title|; params.referrer=document.referrer|; /Window對(duì)象數(shù)據(jù) if(window&window.screen) params.sh=window.screen.height|0; params.sw=window.screen.width|0; params.cd=window.screen.colorDepth|0; /navigator對(duì)象數(shù)據(jù) if(navigator) params.lang=navigator.language|; /解析_maq配置 if(_maq) for(variin_maq) switch(_maqi0) case_setAccount: params.account=_maqi1; break; default: break; /拼接參數(shù)串 varargs=; for(variinparams) if(args!=) args+=&; args+=i+=+encodeURIComponent(paramsi); /通過(guò)Image對(duì)象請(qǐng)求后端腳本 varimg=newImage(1,1); img.src=/1.gif?+args; )();整個(gè)腳本放在匿名函數(shù)里,確保不會(huì)污染全局環(huán)境。功能在原理一節(jié)已經(jīng)說(shuō)明,不再贅述。其中1.gif是后端腳本。日志格式日志采用每行一條記錄的方式,采用不可見(jiàn)字符A(ascii碼0x01,Linux下可通過(guò)ctrl + v ctrl + a輸入,下文均用“A”表示不可見(jiàn)字符0x01),具體格式如下:時(shí)間AIPA域名AURLA頁(yè)面標(biāo)題AReferrerA分辨率高A分辨率寬A顏色深度A語(yǔ)言A客戶端信息A用戶標(biāo)識(shí)A網(wǎng)站標(biāo)識(shí)后端腳本為了簡(jiǎn)單和效率考慮,我打算直接使用nginx的access_log做日志收集,不過(guò)有個(gè)問(wèn)題就是nginx配置本身的邏輯表達(dá)能力有限,所以我選用了OpenResty做這個(gè)事情。OpenResty是一個(gè)基于Nginx擴(kuò)展出的高性能應(yīng)用開(kāi)發(fā)平臺(tái),內(nèi)部集成了諸多有用的模塊,其中的核心是通過(guò)ngx_lua模塊集成了Lua,從而在nginx配置文件中可以通過(guò)Lua來(lái)表述業(yè)務(wù)。關(guān)于這個(gè)平臺(tái)我這里不做過(guò)多介紹,感興趣的同學(xué)可以參考其官方網(wǎng)站/,或者這里有其作者章亦春(agentzh)做的一個(gè)非常有愛(ài)的介紹OpenResty的slide:/misc/slides/ngx-openresty-ecosystem/,關(guān)于ngx_lua可以參考:/chaoslawful/lua-nginx-module。首先,需要在nginx的配置文件中定義日志格式:log_formattick$msecA$remote_addrA$u_domainA$u_urlA$u_titleA$u_referrerA$u_shA$u_swA$u_cdA$u_langA$http_user_agentA$u_utraceA$u_account;注意這里以u(píng)_開(kāi)頭的是我們待會(huì)會(huì)自己定義的變量,其它的是nginx內(nèi)置變量。然后是核心的兩個(gè)location:location/1.gif #偽裝成gif文件 default_typeimage/gif; #本身關(guān)閉access_log,通過(guò)subrequest記錄log access_logoff; access_by_lua -用戶跟蹤cookie名為_(kāi)utrace localuid=ngx.var.cookie_utrace ifnotuidthen -如果沒(méi)有則生成一個(gè)跟蹤cookie,算法為md5(時(shí)間戳+IP+客戶端信息) uid=ngx.md5(ngx.now().ngx.var.remote_addr.ngx.var.http_user_agent) end ngx.headerSet-Cookie=_utrace=.uid.;path=/ ifngx.var.arg_domainthen -通過(guò)subrequest到/i-log記錄日志,將參數(shù)和用戶跟蹤cookie帶過(guò)去 ngx.location.capture(/i-log?.ngx.var.args.&utrace=.uid) end ; #此請(qǐng)求不緩存 add_headerExpiresFri,01Jan198000:00:00GMT; add_headerPragmano-cache; add_headerCache-Controlno-cache,max-age=0,must-revalidate; #返回一個(gè)11的空gif圖片 empty_gif; location/i-log #內(nèi)部location,不允許外部直接訪問(wèn) internal; #設(shè)置變量,注意需要unescape set_unescape_uri$u_domain$arg_domain; set_unescape_uri$u_url$arg_url; set_unescape_uri$u_title$arg_title; set_unescape_uri$u_referrer$arg_referrer; set_unescape_uri$u_sh$arg_sh; set_unescape_uri$u_sw$arg_sw; set_unescape_uri$u_cd$arg_cd; set_unescape_uri$u_lang$arg_lang; set_unescape_uri$u_utrace$arg_utrace; set_unescape_uri$u_account$arg_account; #打開(kāi)日志 log_subrequeston; #記錄日志到ma.log,實(shí)際應(yīng)用中最好加buffer,格式為tick access_log/path/to/logs/directory/ma.logtick; #輸出空字符串 echo; 要完全解釋這段腳本的每一個(gè)細(xì)節(jié)有點(diǎn)超出本文的范圍,而且用到了諸多第三方ngxin模塊(全都包含在OpenResty中了),重點(diǎn)的地方我都用注釋標(biāo)出來(lái)了,可以不用完全理解每一行的意義,只要大約知道這個(gè)配置完成了我們?cè)谠硪还?jié)提到的后端邏輯就可以了。日志輪轉(zhuǎn)真正的日志收集系統(tǒng)訪問(wèn)日志會(huì)非常多,時(shí)間一長(zhǎng)文件變得很大,而且日志放在一個(gè)文件不便于管理。所以通常要按時(shí)間段將日志切分,例如每天或每小時(shí)切分一個(gè)日志。我這里為了效果明顯,每一小時(shí)切分一個(gè)日志。我是通過(guò)crontab定時(shí)調(diào)用一個(gè)shell腳本實(shí)現(xiàn)的,shell腳本如下:_prefix=/path/to/nginxtime=date+%Y%m%d%Hmv$_prefix/logs/ma.log$_prefix/logs/ma/ma-$time.logkill-USR1cat$_prefix/logs/nginx.pid這個(gè)腳本將ma.log移動(dòng)到指定文件夾并重命名為ma-yyyymmddhh.log,然后向nginx發(fā)送USR1信號(hào)令其重新打開(kāi)日志文件。然后再/etc/crontab里加入一行:59*root/path/to/directory/rotatelog.sh在每個(gè)小時(shí)的59分啟動(dòng)這個(gè)腳本進(jìn)行日志輪轉(zhuǎn)操作。測(cè)試下面可以測(cè)試這個(gè)系統(tǒng)是否能正常運(yùn)行了。我昨天就在我的博客中埋了相關(guān)的點(diǎn),通過(guò)http抓包可以看到ma.js和1.gif已經(jīng)被正確請(qǐng)求:圖6. http包分析ma.js和1.gif的請(qǐng)求同時(shí)可以看一下1.gif的請(qǐng)求參數(shù):圖7. 1.gif的請(qǐng)求參數(shù)相關(guān)信息確實(shí)也放在了請(qǐng)求參數(shù)中。然后我tail打開(kāi)日志文件,然后刷新一下頁(yè)面,因?yàn)闆](méi)有設(shè)access log buffer, 我立即得到了一條新日志:1351060731.360AAA/ACodingLabsAA1024A1280A24Azh-CNAMozilla/5.0(Macintosh;IntelMacOSX10_8_2)AppleWebKit/5
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 校慶節(jié)日活動(dòng)方案
- 數(shù)學(xué)學(xué)習(xí)任務(wù)活動(dòng)方案
- 新年扶貧活動(dòng)方案
- 新疆憲法活動(dòng)日活動(dòng)方案
- 新都最后一公里活動(dòng)方案
- 施工隊(duì)做活動(dòng)方案
- 旅游春季推介會(huì)活動(dòng)方案
- 無(wú)人機(jī)公司市場(chǎng)策劃方案
- 日化元旦活動(dòng)方案
- 日韓活動(dòng)策劃方案
- 《云南教育強(qiáng)省建設(shè)規(guī)劃綱要(2024-2035年)》解讀培訓(xùn)
- 第四章美容手術(shù)基本知識(shí)及技術(shù)美容外科學(xué)概論講解
- 2025年中鐵交通投資集團(tuán)有限公司招聘筆試參考題庫(kù)含答案解析
- 滬教版(五四學(xué)制)(2024)六年級(jí)下冊(cè)單詞表+默寫單
- 酒店中央空調(diào)維護(hù)合同
- (2025)時(shí)事政治題庫(kù)(含參考答案)
- 【MOOC期末】《中國(guó)哲學(xué)》(北京師范大學(xué)) 期末中國(guó)大學(xué)慕課答案
- GB/T 18916.65-2024工業(yè)用水定額第65部分:飲料
- 廚師高級(jí)技師論文范文
- 口腔科醫(yī)療垃圾的分類及處理方法
- 2025年工地安全生產(chǎn)月活動(dòng)方案范文
評(píng)論
0/150
提交評(píng)論