百度统计代码如何模拟
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<=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个请求
- 加载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支持
如果你是程序员或者博主,是不是窥探出利用价值了呢?
正文到此结束