原创

百度统计代码如何模拟

1、前言

国内大多数站长可能都在用百度统计。统计的使用方法也很简单,只要在需要统计的页面底部加上统计代码即可。然后打开百度统计的后台,就能看到访客信息,包括入口页面,停留时间,跳出率等等,很是方便。

使用当然是会用,但是随着不断成长,逐渐开始考虑一些事情,比如百度统计只是一行JS怎么就实现统计了呢?如果不打开网页,是不是能利用脚本模拟这一过程呢?

2、统计代码

首先,百度统计要求网站必须嵌入一段JS代码,大概是长这个样子的。

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

去除掉多余的代码,得到最重要的一行

https://hm.baidu.com/hm.js?65e1c6689693082cffb3b7e1f2d8027f

即引入这个JS文件就能实现统计了,问题后边的32位字符串就是每个站点特有的统计ID

3、hm.js做了些什么

该代码加载时,会往用户浏览器中写入名为“HMACCOUNT”的永久cookie,有效期至2038年,以此来区分用户身份。

同时会获取客户端环境,包括浏览器版本,屏幕分辨率,色深,语言等信息。

参数 说明
ci url参数hmci的值
ck 是否支持cookie
cl 颜色深度 如 “32-bit”
cm url参数hmmd的值
cp url参数hmpl的值
cw url参数hmkw的值
ds 屏幕尺寸,如 '1024x768'
ep 初始值为'0',时间变量,反映页面停留时间,格式大概是:现在时间-载入时间+“,”+另一个很小的时间值
et 初始值为'0',如果ep时间变量不是0的话,它会变成其他
fl flash版本
ja java支持 1
ln 语言 zh-cn
lo 不知道,一般为0
lt 日期 time.time(),如“1327847756”, 在首次请求没有
nv 不知道,一般为1或者0
rnd 十位随机数字
sb 如果是360se浏览器该值等于‘17’
se 和搜索引擎相关
si 统计代码id
st 不确定
su 上一页document.referrer
u 入口页面
sw 不知道,估计和搜索引擎有关,一般为空
sse 不知道,估计和搜索引擎有关,一般为空
v 统计代码的版本 ,目前该值为“1.2.30”

4、发送请求

当获取到所有信息的时候,就可以向服务器提交请求了,将之前获取到的参数进行整合,并以这些参数为后缀请求hm.gif,大概是这样一个地址

https://hm.baidu.com/hm.gif?cc=1&ck=1&cl=24-bit&ds=1920x1080&vl=937&et=0&ja=0&ln=zh-cn&lo=0&lt=1644389470&rnd=692033802&si=99f259e8c1db2b5724781c9ef9612de2&su=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DdKTs8TpNPIBxHA0FzBvFYWcMmRaO0U1JVth3YfAEmT3duPGgfX5TB-wNCTRG8tWz%26wd%3D%26eqid%3Dad168783000bcb1e000000045d3a5a9f&v=1.2.89&lv=3&sn=50785&r=0&ww=1028&ct=!!&u=https%3A%2F%2Fwww.chenzhuofan.top%2F%23%25E7%25A7%2581%25E5%25AF%2586%25E8%258A%25B1%25E5%259B%25AD&tt=%E7%A8%8B%E5%BA%8F%E5%91%98%E5%AF%BC%E8%88%AA%E7%BD%91

5、模拟访问

既然了解了请求原理,那能不能用脚本实现模拟访问呢?答案当然是可以的

6、百度统计的4个请求

通过控制台我们可以发现,每访问一个页面都会产生4个请求

百度统计 4个请求

  • 加载hm.js
  • 加载完毕时候出发两次请求,并传递参数
  • 退出页面时候,发出一次请求,并传递参数

实际模拟时,只需要前三次请求即可在访问记录中看到访客记录。

7、代码实现

7.1、java实现

package tech.baiduseo;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.google.common.collect.Maps;
import com.google.gson.Gson;
import lombok.Data;
import org.jsoup.helper.StringUtil;
import tech.chenxing.okhttp3.OkHttpUtil;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.text.MessageFormat;
import java.util.Map;
import java.util.Random;

@Data
public class BaiduSeo {
    private String Referer = "http://www.lixin.me";
    private String BaiduID = "";
    private String Hjs = "http://hm.baidu.com/h.js?";
    private String Hgif = "http://hm.baidu.com/hm.gif?";
    private String TargetPage = "/www.lixin.me";
    private String UserAgent =
            "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)"; // IE9
    private String MyData =
            " {'cc': '1', 'ck': '1', 'cl': '32-bit', 'ds': '1024x768', 'et': '0', 'ep': '0', 'fl': '11.0', 'ja': '1',\n"
                    + "            'ln': 'zh-cn', 'lo': '0', 'nv': '1', 'st': '3', 'v': '1.0.17'}";
    private Map<String, String> mapData = Maps.newHashMap();

    public BaiduSeo(String baiduID, String referer, String targetPage) {
        this.BaiduID = baiduID;
        this.Referer = referer;
        this.TargetPage = targetPage;
        mapData = new Gson().fromJson(MyData, Map.class);
        mapData.put("si", baiduID);
       mapData.put("su", referer);
       mapData.put("u", targetPage);    
    }

    public void run() throws UnsupportedEncodingException {
        Map<String, String> mapHeader = Maps.newConcurrentMap();
        mapHeader.put("Referer", this.getReferer());
        mapHeader.put("User-Agent", this.getUserAgent());
        OkHttpUtil.getInstance().getData(this.Hjs + this.getBaiduID(), mapHeader);

        mapData.put("rnd", String.valueOf(new Random().nextInt(1) * 2147483647));
        mapData.put("lt", String.valueOf(System.currentTimeMillis()));

        String finalUrl = getRightUrl(this.getHgif(), mapData);
        OkHttpUtil.getInstance().getData(finalUrl,mapHeader);

        mapData.put("rnd", String.valueOf(new Random().nextInt(1) * 2147483647));
        mapData.put("et", "3");
        mapData.put("ep", "2000,100");

        String finalUrl1 = getRightUrl(this.getHgif(), mapData);
        OkHttpUtil.getInstance().getData(finalUrl1, mapHeader);
    }


    private String getRightUrl(String url, Map<String, String> map)
            throws UnsupportedEncodingException {
        String param = "";
        for (Map.Entry<String, String> entry : map.entrySet()) {
            if (StrUtil.isBlank(entry.getKey()) || StrUtil.isBlank(entry.getValue())) {
                continue;
            }
            param +=
                    MessageFormat.format(
                            "&{0}={1}",
                            entry.getKey(), URLEncoder.encode(entry.getValue(), "UTF-8"));
        }
        System.out.println(url + param.substring(1));
        return url + param.substring(1);
    }

    public static void main(String[] args) throws UnsupportedEncodingException {
        BaiduSeo baiduSeo =
                new BaiduSeo(
                        "xxxxx",
                        "https://juejin.cn/career/",
                        "https://juejin.cn/search");
        baiduSeo.run();
        System.out.println("xxxxx");
    }
}

7.2、python实现

import urllib
import random
import math
import time
from http import cookiejar


########################################################################
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.parse.quote(self.Referer)
        pass

    def run(self, timeout=5):
        # 通过cookieJar()类构建一个cookieJar()对象,用来保存cookie的值

        cookie = cookiejar.CookieJar()

        # 通过HTTPCookieProcessor()处理器类构建一个处理器对象,用来处理cookie
        # 参数就是构建的CookieJar()对象
        cookie_handler = urllib.request.HTTPCookieProcessor(cookie)

        # 构建一个自定义的opener
        opener = urllib.request.build_opener(cookie_handler)

        opener.addheaders = [("Referer", self.TargetPage), ("User-Agent", self.UserAgent)]

        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.parse.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.parse.urlencode(self.MyData), timeout=timeout).info()



if __name__ == "__main__":
    a = Baidu('xxxxxx', 'https://www.google.com/', 'https://www.google.com/search')
    a.run()

7.3、php实现

function baiduVisit($bdId,$targetUrl,$referer = 'yantuz.cn',$visitTimes=1){
 $bdjs = 'https://hm.baidu.com/hm.js?';
 $bdgif = 'https://hm.baidu.com/hm.gif?';
 //$bdId = '65e1c6689693082cffb3b7e1f2d8027f';

$arr=array(
 'cc'=> '0',
 'ck'=> '1',
 'cl'=>'24-bit',
 'ds'=> '1440x900',
 'vl'=> '747',
 #'ep'=> '6346,2301',#时间
 'et'=> '0', #3
 'fl'=> '29.0',
 'ja'=> '0',
 'ln'=> 'zh-cn',
 'lo'=> '0',
 'lt'=> time(),
 'rnd'=> rand(1000000000,2000000000), #random
 'si'=> $bdId,
 'v'=> '1.2.30',
 'lv'=> '3',
 'sn'=> '25573',#25581
 'su'=> $referer, #请求来源

#'ct'=> '!!',
 #'tt'=> '页面标题'
 );
 //echo http_build_query($arr);

// Create a stream
 $opts = array(
 'http'=>array(
 'method'=>"GET",
 'header'=>"Accept-language: cn\r\n"."referer:$targetUrl",
 'timeout'=>3,
 )
 );
 $context = stream_context_create($opts);
 $url1 = $bdjs.$bdId;
 //echo $url1.'<br />';
 $arr1 = array_merge($arr,array('ep'=> '2302,153','u'=> $referer));
 $arr1['et'] = 3;
 $url2 = $bdgif.http_build_query($arr1);
 //echo $url2.'<br />';
 $arr2 = array_merge($arr,array('ct'=> '!!','tt'=> 'title'));
 $url3 = $bdgif.http_build_query($arr2);
 //echo $url3.'<br />';

for ($x=0; $x<$visitTimes; $x++) {
 file_get_contents($url1, false, $context);
 file_get_contents($url2, false, $context);
 file_get_contents($url3, false, $context);
 //echo $x;
 }
}

baiduVisit('百度ID','https://yantuz.cn/');

测试效果

代码的关键是:需要启用httputil工具类的cookies支持

思考

​ 如果你是程序员或者博主,是不是窥探出利用价值了呢?

正文到此结束
本文目录