您的位置:澳门新葡萄京最大平台 > 动作小游戏 > 百度统计的JS脚本原理分析

百度统计的JS脚本原理分析

发布时间:2019-09-06 15:46编辑:动作小游戏浏览(137)

    首先,百度统计会要求我们在要统计的页面中嵌入一段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,如:   。然后请求该图片。

    百度统计服务端,通过接收到这个请求,并从这个图片的网址附带的参数获取相关信息,记录访客访问记录;当页面被用户关闭的时候,同样会触发一次请求hm.gif的过程,但这个过程不是所有浏览器和所有关闭动作都支持。

     

    接下来通过程序模拟这一过程:

    首先,使用Wireshark(一款网络抓包工具)对浏览器实际的过程进行捕获。首先是使用ie打开一个有超链接链接到有百度统计的网站,加载完毕后关闭浏览器。最后在Wireshark上得到这么的网络数据包。




    可以发现,浏览器总共向服务器端发送了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=''
    TargetPage='/www.lixin.me'
    BaiduID=''
    Hjs=""
    Hgif=""
    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','')
    a.run()

     

    本文由澳门新葡萄京最大平台发布于动作小游戏,转载请注明出处:百度统计的JS脚本原理分析

    关键词: