介绍
使用博客园的朋友都知道,博客园提供了强大的定制功能,供用户定制自己的博客。其中很多人在侧边栏添加了”访问统计“组件,用于展示博客的统计数据,主要是按国家划分的访问量,如下图:
而这个”访问统计“组件的提供方大部分来自国外,如flagcounter,amazingcounters等,因此服务在稳定性和传输速度上相对来说不够好,那如何解决国外服务提供商提供的服务体验不够好而国内的又没有类似的可直接使用的服务呢?答案是自己造一个。
原理分析
首先我们先分析一下访问统计功能的核心功能,共有三个:数据收集,IP地址转物理地址和数据获取。以flagcounter为例,它提供的是一个HTML代码块,如下:
详细代码如下:
<a href="https://info.flagcounter.com/LGdk"
><img
src="https://s11.flagcounter.com/count2/LGdk/bg_FFFFFF/txt_000000/border_CCCCCC/columns_2/maxflags_10/viewers_0/labels_0/pageviews_0/flags_0/percent_0/"
alt="Flag Counter"
border="0"
/>
</a>
其中核心的部分为<img>
标签,src
属性中的链接便是用于收集数据和获取数据,至于IP地址转物理地址的功能则是在服务器端实现。
方案设计
通过上述的原理分析,我们要做的主要也是数据收集,IP地址转物理地址和数据获取这三个功能。有两种方案可以实现:
- 自己实现:功能完全可定制,但是要花较多时间
- 部分功能使用现有服务,自己实现剩余功能:功能受限于服务提供商,但功能稳定,也省时间
关于方案2,国内有很多可以给个人免费使用的网站统计服务,如百度统计,友盟等,360分析等,提供了数据收集和IP地址转物理地址的功能,稳定性好且传输速度快。关于数据获取,这个是要我们自己开发的,统计服务一般会提供API,我们可以将数据包装成html代码,动态加载到博客中。
这里为了节省时间,我们以选择方案2,统计服务选择百度统计,来进行系统搭建。
关于百度统计在博客园的集成,可以参考:在博客园里使用百度统计
具体实现
在百度开发者平台创建一个工程
百度统计API的使用涉及到百度开发者,需要先注册开发者然后创建一个工程:
需要设置"授权回调页":
集成百度统计API
具体包括两个步骤:
- 将百度统计服务授权给上一步创建的工程:这里需要用到上一个创建的工程的CLIENT_ID,CLIENT_SECRET和REDIRECT_URI
- 调用统计API:个人用于用的是百度账号,百度商业账号
百度统计提供了"按国家"和"按省"两个指标来获取访问量的地域分布,这个可以按喜好选择。
数据返回
首先将如下代码块添加到博客园的html代码框中,获取到数据之后,我们将数据格式化成html代码块,返回给前端,然后动态插入到侧边栏。
<script>
let url =
'https://counter.toyfun.cn/api/counters/b035d53423sds317248696c2c0b/analytics';
fetch(url).then(res => {
if (res.ok) {
res.text().then(txt => {
let element = document.getElementById('sideBarMain');
var div = document.createElement('div');
div.className = 'newsItem';
div.innerHTML = txt;
element.insertBefore(div, element.childNodes[0]);
});
}
});
</script>
项目实例
技术栈
- 前端页面:HTML+CSS+JavaScript+Pug模板引擎
- 后端:Express框架
- 存储:SQLite
关键代码
- 百度统计API的集成:
async function getTokenByCode(code, clientId, clientSecret, redirectUri) {}
async function refreshToken(refreshToken, clientId, clientSecret) {}
async function getSites(accessToken) {}
async function getAnalytics(accessToken, params = {}) {}
- 数据库的连接和操作
async function getDB() {
if (!db) {
await new Promise((res, rej) => {
db = new sqlite3.Database(filename, error => {
...
});
});
}
return db;
}
async function run(sql, params) {
let db = await getDB();
return new Promise((res, rej) => {
db.run(sql, params, (error, result) => {
...
});
});
}
- 接口路由
router.get('/counters/:id/analytics', async (req, res) => {
// ...
// get analytics
let paramsForAnalytics = {
site_id,
...
};
let result = await baiduAnalyticsService.getAnalytics(
accessToken,
paramsForAnalytics
);
let data=parseResult(result);
// render html template
let locals = { total, data };;
let html = await htmlTemplateService.render('analytics', locals);
res.send(html);
});
项目成果
项目网站:https://counter.toyfun.cn/
最终的效果图如下:
当然目前的效果比较简单,只是一个简单的表格,后续也可以将其美化,比如:添加国家地图(参考flagcounter),提供多种显示样式(如访问趋势,停留时间,设备类型等等),这些大家可以自由发挥。
总结
本文介绍了博客园访问统计的原理,并提供了具体的方案设计和实现,核心功能有三个:数据收集,IP地址转物理地址和数据获取。有兴趣的朋友可以自己动手来写一个,也可以直接使用本文提供的现成产品。