如何把百度統計代碼放入JS文件中?百度統計的JS腳本原理分析


<script>
var _hmt = _hmt || [];
(function() {
  var hm = document.createElement("script");
  hm.src = "https://hm.baidu.com/hm.js?68df874fd78fd8f5cdv45fd470a49b12";
  var s = document.getElementsByTagName("script")[0]; 
  s.parentNode.insertBefore(hm, s);
})();
</script>

首先,百度統計會要求我們在要統計的頁面中嵌入一段js語句,類似如下:

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

 

這段js,實質上是往頁面中引入hm.baidu.com/h.js的這段代碼,該代碼的內容會根據后面的參數有所不同,h.js?后面的參數就是你在百度統計里的id。

獲取該h.js代碼的同時,百度統計會往你的瀏覽器寫入一個名字為“HMACCOUNT”的cookie,該cookie的過期時間為2038年,所以只要你沒有清空瀏覽器cookie,基本就永不過期。

h.js被下載后,便執行其腳本獲取一些瀏覽器相關信息和訪問來源,獲取的信息包括屏幕尺寸、顏色深度、flash版本、用戶語言等。

從js代碼中可以得到,所有參數包括這些:”cc,cf,ci,ck,cl,cm,cp,cw,ds,ep,et,fl,ja,ln,lo,lt,nv,rnd,sb,se,si,st,su,sw,sse,v”。這些參數的意義大致如下:

cc: 不知道,一般為1
cf:url參數hmsr的值
ci:url參數hmci的值
ck:是否支持cookie 1:0
cl:顏色深度 如 “32-bit”
cm:url參數hmmd的值
cp:url參數hmpl的值
cw:url參數hmkw的值
ds:屏幕尺寸,如 ’1024×768′
ep:初始值為’0′,時間變量,反映頁面停留時間,格式大概是:現在時間-載入時間+“,”+另一個很小的時間值
et:初始值為’0′,如果ep時間變量不是0的話,它會變成其他
fl:flash版本
ja:java支持 1:0
ln:語言 zh-cn
lo: 不知道,一般為0
lt:日期 time.time(),如“1327847756”, 在首次請求沒有
nv: 不知道,一般為1或者0
rnd:十位隨機數字
sb:如果是360se瀏覽器該值等於‘17’
se: 和搜索引擎相關
si:統計代碼id
st:
su:上一頁document.referrer
sw: 不知道,估計和搜索引擎有關,一般為空
sse:不知道,估計和搜索引擎有關,一般為空
v:統計代碼的版本 ,目前該值為“1.0.17”

 

當這些參數都設置完畢了(有些參數並沒有賦值),篩選出已經賦值了的參數,並作為hm.baidu.com/hm.gif的參數拼湊出一個url,如:http://hm.baidu.com/hm.gif?cc=1&ck=1&cl=32-bit&ds=1366×768&ep=0&et=0&fl=11.0&ja=1&ln=zh-cn   。然后請求該圖片。

百度統計服務端,通過接收到這個請求,並從這個圖片的網址附帶的參數獲取相關信息,記錄訪客訪問記錄;當頁面被用戶關閉的時候,同樣會觸發一次請求hm.gif的過程,但這個過程不是所有瀏覽器和所有關閉動作都支持。

 

接下來通過程序模擬這一過程:

首先,使用Wireshark(一款網絡抓包工具)對瀏覽器實際的過程進行捕獲。首先是使用ie打開一個有超鏈接鏈接到有百度統計的網站,加載完畢后關閉瀏覽器。最后在Wireshark上得到這么的網絡數據包。

http://hm.baidu.com/h.js?3266e9d3684e7a1307dc7c4b4a64b0ae
http://hm.baidu.com/hm.gif?cc=1&ck=1&cl=32-bit&ds=1366×768&ep=0&et=0&fl=11.0&ja=1&ln=zh-cn&lo=0<=1328171561&nv=1&rnd=2889921&si=3266e9d3684e7a1307dc7c4b4a64b0ae&st=3&su=http%3A%2F%2Fwww.zhanghangbo.com%2F&v=1.0.17
http://hm.baidu.com/hm.gif?cc=1&ck=1&cl=32-bit&ds=1366×768&ep=7289%2C115&et=3&fl=11.0&ja=1&ln=zh-cn&lo=0<=1328171561&nv=1&rnd=1444115283&si=3266e9d3684e7a1307dc7c4b4a64b0ae&st=3&su=http%3A%2F%2Fwww.zhanghangbo.com%2F&v=1.0.17
http://hm.baidu.com/hm.gif?cc=1&ck=1&cl=32-bit&ds=1366×768&ep=212486%2C4614&et=3&fl=11.0&ja=1&ln=zh-cn&lo=0<=1328171541&nv=1&rnd=1067394506&si=0f9e2caa14d6d0a51371b168d182314a&st=1&v=1.0.17

可以發現,瀏覽器總共向服務器端發送了4次請求:

  1. 請求一段js腳本。
  2. 加載完畢時候出發一次請求,並傳遞參數
  3. 退出頁面時候,發出一次請求,並傳遞參數,與上面對比,發現ep參數有變化。

        百度統計是基於cookie的,當請求js腳本的時候,會在你電腦里保存一個永久cookie,該cookie作為你的用戶標識。同時發現,但退出時候參數ep從最開始的0變為了“7289%2C115”,轉義后是“7289,115”這是兩個毫秒單位,即7.2秒和0.1秒的意思。同時前兩次請求hm.gif的時候lt參數(時間,javascript:(new Date).getTime())是不變的。rnd隨機數每次都變。

下面我們就來模擬一次請求,本次使用的python語言。

import urllib2
import urllib 
import random
import math
import urlparse
import time
import cookielib

########################################################################
class Baidu:
""""""
Referer='http://www.lixin.me'
TargetPage='/www.lixin.me'
BaiduID=''
Hjs="http://hm.baidu.com/h.js?"
Hgif="http://hm.baidu.com/hm.gif?"
UserAgent='Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)' #IE9
MyData={'cc':'1','ck':'1','cl':'32-bit','ds':'1024x768','et':'0','ep':'0','fl':'11.0','ja':'1','ln':'zh-cn','lo':'0','nv':'1','st':'3','v':'1.0.17'}
#----------------------------------------------------------------------

def __init__(self,baiduID,targetPage=None,refererPage=None):
"""Constructor"""
self.TargetPage=targetPage or self.TargetPage
self.Referer=refererPage or self.Referer
self.BaiduID=baiduID
self.MyData['si']=self.BaiduID
self.MyData['su']=urllib.quote(self.Referer)
pass
def run(self,timeout=5):
cj=cookielib.CookieJar()
opener=urllib2.build_opener(urllib2.HTTPCookieProcessor(cj)) 
opener.addheaders=[("Referer",self.TargetPage),("User-Agent",self.UserAgent)]
try:
response=opener.open(self.Hjs+self.BaiduID).info()
self.MyData['rnd']=int(random.random()*2147483647 )
self.MyData['lt']=int(time.time())
fullurl=self.Hgif+urllib.urlencode(self.MyData)
response2=opener.open(fullurl,timeout=timeout).info()
self.MyData['rnd']=int(random.random()*2147483647 )
self.MyData['et']='3'
self.MyData['ep']='2000,100'
response3=opener.open(self.Hgif+urllib.urlencode(self.MyData),timeout=timeout).info()
pass
except urllib2.HTTPError ,ex:
print ex.code 
pass
except urllib2.URLError,ex:
print ex.reason
pass
pass



if __name__ =="__main__":
a=Baidu('百度統計id','http://www.lixin.me/blog/test4','www.lixin.com.cn')
a.run()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM