本文最后更新于:2024年5月7日 下午
2022年8月,LeanCloud 国际版不再为来自中国大陆的 IP 提供服务,基于 LeanCloud 的站点统计因此失效,本文基于 Umami 的统计信息自建 PV UV 统计后台,解决上述问题。
前端、后端小白,对Python比较熟悉,后端代码用 Python 实现的,仅仅完成了功能,过程也比较繁琐,思路过程供大家参考
背景
- 基于某些原因,LeanCloud 国际版不再为来自中国大陆的 IP 提供服务
- 在 Hexo Fluid 主题中使用 LeanCloud 的主要有 站点/文章 PV、UV 统计和评论系统
- 截止当前(2022年8月15日)Walline 的 LeanCloud 数据库可以正常访问,即仍在正常运转,可能是有后台的代理服务器
- 站点 PV、UV 凉了,于是自建
功能需求
- 全站页面浏览量 (PV) 统计
- 全站用户访问量 (UV) 统计
- 当前在线用户数统计
- 文章页面浏览量统计
- 文章用户访问量统计
原理思路
计数工具
- 讲道理只要有看门的 callback 将用户信息发送到后台进行统计并想办法显示统计数据即可
- github 上有很多工程可以使用
- 我在之前搭建了基于 Google 统计的工具 Umami
- 正好 Umami 有方便的 API 接口 可以调用
于是决定基于这款工具开发 PV UV 统计
LeanCloud 数据继承
-
如果直接放弃 LeanCloud 那么之前的访问数据就清零了
-
要是觉得可惜的话可以将 LeanCloud 数据下载下来,在 Umami 计数结果中加上 LeanCloud 的以往数据即可
当然了,优秀的同学也可以去改 Umami 的数据库
后台代码
- 需要后端服务器监听端口,负责为显示 PVUV 数据请求提供服务
- 核心就是对 Umami API 的封装
- 需要解决跨域访问的问题
前端显示
- 建立几个 span 块,JavaScript 代码动态修改并填入数据内容
https 访问
- https 站点 要求内部链接都是 https
- 于是需要 Nginx 反向代理成 https
插入 Fluid
- 在Fluid 合适的部分插入上述前端代码,完成在 Hexo 中的显示
实现流程
计数工具
- 搭建个人 Umami 统计平台: 站统计工具 Umami 安装部署教程
LeanCloud 数据继承
-
如果有之前的 LeanCloud 国际版数据可以导出为 Json
-
想办法(大陆IP无法访问)进入 国际版 LeanCloud
-
导出数据
-
导出成功
-
随后可以看到数据库表单基本整理成了json文件下载了下来
-
对于本文应用来说,核心文件在
Counter.0.jsonl
文件中,该文件主要内容为 json 格式,删去第一行稍加修改即可作为正常 json 文件使用 -
之后可以按照自己的需求整理成方便可用的计数文件
后台代码
依赖 Umami 的 API,需要搭建好 API 获取环境
核心代码
1 |
|
-
使用时需要修改
root_url
和header
中的<url-to-umami>
和<your-token>
为你自己的值 -
active_num 函数获取当前活跃用户数
-
PVUV_num 函数获取站点 PV UV 数
-
post_pv 函数获取 post PV UV 数
-
js_str 函数整合 active_num 和 PVUV_num 的结果返回 js 代码
-
self.conter_dict 为 LeanCloud 计数数据备份 Json 字典
-
核心代码的行为:
- 利用 Umami API 获取需要的数据
- 整合成 js 字符串或直接返回数据
- js 串功能为修改ID 为
PVstatic
,UVstatic
和ACTstatic
的元素内容
后端代码
1 |
|
-
使用时将
<your-port>
换为你自己需要监听的端口 -
开放两个路由:
-
statistics 站点 PV UV 和 活跃用户数,返回内容为一段 js 代码
访问示例
-
poststats 文章 PV UV
访问示例
-
搭建服务
-
代码调整好后需要让他在服务器自动运行
-
需要用到 systemctl 工具
-
此处 service 示例代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15[Unit]
Description = Service to count pv,uv for www.zywvvd.com
After = network.target
[Service]
ExecStart = /home/lighthouse/anaconda3/bin/python main.py
WorkingDirectory = /usr/local/static/
StandardOutput = inherit
StandardError = inherit
Restart = always
User = lighthouse
[Install]
WantedBy=multi-user.target -
记得设置开机自动启动
1
sudo systemctl enable pvuv.service
前端显示
网站 PV UV
-
我选择在 Fluid 主题配置文件中加入该部分前端代码
-
打开
Hexo/_config.fluid.yml
文件 -
关闭原始 PV、UV 统计
1
2
3
4
5
6
7
8
9
10
11
12
13
# 展示网站的 PV、UV 统计数
# Display website PV and UV statistics
statistics:
enable: false
# 统计数据来源,使用 leancloud 需要设置 `web_analytics: leancloud` 中的参数;使用 busuanzi 不需要额外设置,但是有时不稳定,另外本地运行时 busuanzi 显示统计数据很大属于正常现象,部署后会正常
# Data source. If use leancloud, you need to set the parameter in `web_analytics: leancloud`
# Options: busuanzi | leancloud
source: "leancloud"
pv_format: "总访问量 {} 次"
uv_format: "总访客数 {} 人"由于 LeanCloud 仅在大陆无法访问,国外网友访问时还是会正常显示一行 PV,UV 统计,为了避免重复把原来的关掉
-
在 footer.content 中加入前端代码
1
2
3
4
5
6<div style="font-size: 0.85rem;">
<span> 总访问量 <span style="color: #d7d8d9;" id="PVstatic">0</span> 次 </span>
<span> 总访客数 <span style="color: #d7d8d9;" id="UVstatic">0</span> 人 </span>
<span> 当前在线 <span style="color: #d7d8d9;" id="ACTstatic">0</span> 人 </span>
<script src="https://<url-to-app>/statistics" defer></script>
</div>
post 文章 PV UV
-
修改 fluid 主题配置文件
Hexo/_config.fluid.yml
,加入新的文章浏览计数来源,我起名叫vvdpostpvuv
1
2
3
4
5
6
7
8
9# 浏览量计数
# Number of visits
views:
enable: true
# 统计数据来源
# Data Source
# Options: busuanzi | leancloud | 自建基于 Umami 统计的 文章PV vvdpostpvuv
source: "vvdpostpvuv"
format: "{} 次" -
打开文件
Hexo/themes/fluid/layout/_partials/post/meta-top.ejs
, 加入新的 else 分支:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42<% } else if (theme.post.meta.views.source === 'busuanzi') { %>
<span id="busuanzi_container_page_pv" style="display: none">
<i class="iconfont icon-eye" aria-hidden="true"></i>
<%- views_texts[0] %><span id="busuanzi_value_page_pv"></span><%- views_texts[1] %>
</span>
<% import_js(theme.static_prefix.busuanzi, 'busuanzi.pure.mini.js', 'defer') %>
<% } else if (theme.post.meta.views.source === 'vvdpostpvuv') { %>
<span id="vvdpost_container_page_pvuv" style="display: none">
<i class="iconfont icon-eye" aria-hidden="true"></i>
<%- views_texts[0] %><span id="vvdpost_value_page_pv">0</span><%- views_texts[1] + '  ' %>
<i class="iconfont icon-users" aria-hidden="true"></i>
<%- views_texts[0] %><span id="vvdpost_value_page_uv">0</span><%- ' 人' %>
</span>
<script>
console.log(window.location.pathname)
var httpRequest = new XMLHttpRequest();
httpRequest.open('POST', 'https://uipv4.zywvvd.com:33030:6101/poststats', true);
httpRequest.setRequestHeader("Content-type","application/json");
httpRequest.send(JSON.stringify(window.location.pathname));
httpRequest.onreadystatechange = function () {//请求后的回调接口,可将请求成功后要执行的程序写在其中
if (httpRequest.readyState == 4 && httpRequest.status == 200) {//验证请求是否发送成功
var json = httpRequest.responseText;//获取到服务端返回的数据
var obj = JSON.parse(json);
console.log(obj.pv);
var pvCtn = document.querySelector('#vvdpost_container_page_pvuv');
console.log(pvCtn);
if (pvCtn) {
var pv_ele = document.querySelector('#vvdpost_value_page_pv');
console.log(pv_ele);
var uv_ele = document.querySelector('#vvdpost_value_page_uv');
console.log(uv_ele);
if (uv_ele && uv_ele) {
pv_ele.innerText = obj.pv;
uv_ele.innerText = obj.uv;
pvCtn.style.display = 'inline';
}
}
}
};
</script>
<% } %>
https 访问
- Nginx 做 ssl 反向代理,给出 https 访问链接、端口
效果展示
- 站点 PV UV
- Post PV UV
参考资料
- https://www.zywvvd.com/notes/tools/umami/umami-api/umami-api/
- https://www.zywvvd.com/notes/tools/umami/umami/
- https://www.cnblogs.com/niuben/p/14676340.html
- https://fontawesome.com/icons/user-group?s=solid
- http://c.biancheng.net/view/9375.html
- https://blog.csdn.net/zyndev/article/details/108659379
文章链接:
https://www.zywvvd.com/notes/hexo/theme/fluid/fluid-build-pvuv-statistics/build-pvuv-statistics/
“觉得不错的话,给点打赏吧 ୧(๑•̀⌄•́๑)૭”
微信支付
支付宝支付