使用MTA HTML5统计API来分析数据
在开发个人博客的时候,用到了腾讯移动分析(MTA),相比其他数据统计平台来说我喜欢她的简洁高效,易上手,同时文档也比较全面,提供了数据接口供用户调用。
在看了MTA演示Demo和官方文档后,我就决定使用 .NET Core将其HTML5统计API进行封装,以供博客直接调用,省去各种鉴权生成sign的操作。
首先需要在MTA官网进行HTML5应用创建,当然她还支持小程序和移动App。

然后就可以看到如上图的应用管理界面,如果你不打算使用其API接口,直接拿到统计代码嵌入在自己网站中即可,不出意外10分钟左右即可查看网站部分指标的实时数据,次日可以查看昨日的全部数据。
接下来继续,在调用MTA接口之前需要先生成sign,
双方维护同一份私钥,在发起请求的时候,发起方(合作方)将当前的请求参数数组,按照key值进行排序,然后'key=value'拼接到加密串后,进行md5的编码。接收方以同样的处理方式,对ts小于或等于30分钟的请求进行处理,sign一致则合法,否则失败。
有了这段算法描述,利用C#代码实现如下:
/// <summary>
/// 生成sign
/// </summary>
/// <param name="keyValues"></param>
/// <returns></returns>
public static string GgenerateSign(this Dictionary<string, string> keyValues)
{
keyValues.Add("app_id", MtaConfig.App_Id);
IDictionary<string, string> sortedParams = new SortedDictionary<string, string>(keyValues);
var iterator = sortedParams.GetEnumerator();
var sb = new StringBuilder();
while (iterator.MoveNext())
{
var key = iterator.Current.Key;
var value = iterator.Current.Value;
if (key.IsNotNullOrEmpty() && value.IsNotNullOrEmpty())
{
sb.Append(key).Append("=").Append(value);
}
}
return (MtaConfig.SECRET_KEY + sb.ToString()).Md5();
}
将参数放入一个字典,并按照key值进行排序。因为所有接口都需要参数app_id,所以将其默认添加进去,不在额外当做参数。
.Md5()是一个扩展方法,将字符串按照MD5方式加密
拿到sign后就可以调用接口了,因为是封装,那么将所有接口都保存为静态变量,代码如下
#region 应用趋势
/// <summary>
/// 应用历史趋势
/// 每天的pv\uv\vv\iv数据
/// </summary>
public static string Ctr_core_data = "https://mta.qq.com/h5/api/ctr_core_data";
/// <summary>
/// 应用实时小时数据
/// 当天每小时的pv\uv\vv\iv数据
/// </summary>
public static string Ctr_realtime = "https://mta.qq.com/h5/api/ctr_realtime/get_by_hour";
/// <summary>
/// 应用心跳数据
/// 当前pv\uv\vv\iv心跳数据数据
/// </summary>
public static string Ctr_realtime_heartbeat = "https://mta.qq.com/h5/api/ctr_realtime/heartbeat";
#endregion
#region 访客分析
/// <summary>
/// 实时访客
/// 在24小时内的实时访客信息
/// </summary>
public static string Ctr_user_realtime = "https://mta.qq.com/h5/api/ctr_user_realtime";
/// <summary>
/// 新老访客比
/// 按天查询当天新访客与旧访客的数量
/// </summary>
public static string Ctr_user_compare = "https://mta.qq.com/h5/api/ctr_user_compare";
/// <summary>
/// 用户画像
/// 查询用户画像数据,包含性别比例、年龄分布、学历分布、职业分布,数据为pv量
/// </summary>
public static string Ctr_user_portrait = "https://mta.qq.com/h5/api/ctr_user_portrait";
#endregion
#region 客户端分析
/// <summary>
/// 地区数据
/// 按天查询地区的pv\uv\vv\iv量
/// </summary>
public static string Ctr_area = "https://mta.qq.com/h5/api/ctr_area/get_by_area";
/// <summary>
/// 省市数据
/// 按天查询省市下有流量的城市的pv\uv\vv\iv量
/// </summary>
public static string Ctr_area_province = "https://mta.qq.com/h5/api/ctr_area/get_by_province";
/// <summary>
/// 运营商
/// 按天查询运营商的pv\uv\vv\iv量
/// </summary>
public static string Ctr_operator = "https://mta.qq.com/h5/api/ctr_operator";
/// <summary>
/// 终端属性列表
/// 按天查询对应属性的终端信息数据
/// </summary>
public static string Ctr_client_para = "https://mta.qq.com/h5/api/ctr_client/get_by_para";
/// <summary>
/// 终端信息
/// 按天查询终端信息数据
/// </summary>
public static string Ctr_client_content = "https://mta.qq.com/h5/api/ctr_client/get_by_content";
#endregion
#region 页面分析
/// <summary>
/// 页面排行-当天实时列表
/// 查询当天所有url的pv\uv\vv\iv数据
/// </summary>
public static string Ctr_page_realtime = "https://mta.qq.com/h5/api/ctr_page/list_all_page_realtime";
/// <summary>
/// 页面排行-离线列表
/// 按天查询所有url的pv\uv\vv\iv数据
/// </summary>
public static string Ctr_page_offline = "https://mta.qq.com/h5/api/ctr_page/list_all_page_offline";
/// <summary>
/// 页面排行-指定查询部分url
/// 按天查询url的pv\uv\vv\iv数据。
/// </summary>
public static string Ctr_page_url = "https://mta.qq.com/h5/api/ctr_page";
/// <summary>
/// 性能监控
/// 按天查询对应省市的访问延时与解析时长
/// </summary>
public static string Ctr_page_speed = "https://mta.qq.com/h5/api/ctr_page_speed";
/// <summary>
/// 访问深度
/// 按天查询用户访问深度
/// </summary>
public static string Ctr_page_depth = "https://mta.qq.com/h5/api/ctr_depth";
#endregion
#region 来源分析
/// <summary>
/// 外部链接
/// 按天查询外部同站链接带来的流量情情况
/// </summary>
public static string Ctr_source_out = "https://mta.qq.com/h5/api/ctr_source_out";
/// <summary>
/// 入口页面
/// 按天查询用户最后访问的进入次数与跳出率
/// </summary>
public static string Ctr_page_land = "https://mta.qq.com/h5/api/ctr_page_land";
/// <summary>
/// 离开页面
/// 按天查询最后访问页面的离次数
/// </summary>
public static string Ctr_page_exit = "https://mta.qq.com/h5/api/ctr_page_exit";
#endregion
#region 自定义事件
/// <summary>
/// 自定义事件
/// 按天查询自定义事件的pv\uv\vv\iv
/// </summary>
public static string Ctr_custom = "https://mta.qq.com/h5/api/ctr_custom";
#endregion
#region 渠道效果统计
/// <summary>
/// 渠道效果统计
/// 按天查询渠道的分析数据
/// </summary>
public static string Ctr_adtag = "https://mta.qq.com/h5/api/ctr_adtag";
#endregion
接下来对照文档生成URL的查询参数,然后访问接口拿到返回数据
/// <summary>
/// 生成URL查询参数
/// </summary>
/// <param name="keyValues"></param>
/// <returns></returns>
public static string GgenerateQuery(this Dictionary<string, string> keyValues)
{
var sign = keyValues.GgenerateSign();
var query = "?";
keyValues.ForEach(x =>
{
query += $"{x.Key}={x.Value}&";
});
return $"{query}sign={sign}";
}
/// <summary>
/// 获取MTA接口返回数据
/// </summary>
/// <param name="keyValues"></param>
/// <returns></returns>
public static async Task<string> GetMTAData(this Dictionary<string, string> keyValues, string api)
{
var url = $"{api}{keyValues.GgenerateQuery()}";
// HWRequest()和HWRequestResult()是扩展方法,可以选择自己熟悉HTTP请求方法
var hwr = url.HWRequest();
string result = hwr.HWRequestResult();
return await Task.FromResult(result);
}
到这里基本上就结束了,只需对照MTA文档传入对应的参数即可拿到返回的数据了。
以其中一个接口为例,应用历史趋势,获取每天的pv、uv、vv、iv数据
/// <summary>
/// 应用历史趋势
/// 每天的pv\uv\vv\iv数据
/// </summary>
/// <param name="start_date">开始时间(Y-m-d)</param>
/// <param name="end_date">结束时间(Y-m-d)</param>
/// <param name="idx">查询指标(pv,uv,vv,iv),使用“,”间隔</param>
/// <returns></returns>
public async Task<string> Ctr_core_data(string start_date, string end_date, string idx)
{
var keyValues = new Dictionary<string, string>
{
{ "start_date", start_date },
{ "end_date", end_date },
{ "idx", idx }
};
return await keyValues.GetMTAData(MtaConfig.Ctr_core_data);
}
在controller中进行调用
/// <summary>
/// 应用历史趋势
/// 每天的pv\uv\vv\iv数据
/// </summary>
/// <param name="start_date">开始时间(Y-m-d)</param>
/// <param name="end_date">结束时间(Y-m-d)</param>
/// <param name="idx">查询指标(pv,uv,vv,iv),使用“,”间隔</param>
/// <returns></returns>
[HttpGet]
[Route("ctr_core_data")]
public async Task<dynamic> Ctr_core_data(string start_date, string end_date, string idx)
{
var result = await _mtaService.Ctr_core_data(start_date, end_date, idx);
return result.DeserializeFromJson<dynamic>();
}
查询结果看下图

详细代码可参考:https://github.com/Meowv/Blog/tree/master/src/MeowvBlog.MTA
使用MTA HTML5统计API来分析数据的更多相关文章
- html5统计数据上报API:SendBeacon
公司为了精准的了解自己产品的用户使用情况,通常会对用户数据进行统计分析,获取pv.uv.页面留存率.访问设备等信息.与之相关的就是客户端的数据采集,然后上报的服务端.为了保证数据的准确性,就需要保证数 ...
- Python获得百度统计API的数据并发送邮件
Python获得百度统计API的数据并发送邮件 小工具 本来这么晚是不准备写博客的,当是想到了那个狗子绝对会在开学的时候跟我逼逼这个事情,所以,还是老老实实地写一下吧. Baidu统计API的使 ...
- HTML5 程序设计 - 使用HTML5 Canvas API
请你跟着本篇示例代码实现每个示例,30分钟后,你会高喊:“HTML5 Canvas?!在哥面前,那都不是事儿!” 呵呵.不要被滚动条吓到,很多都是代码和图片.我没有分开写,不过上面给大家提供了目录,方 ...
- 开大你的音响,感受HTML5 Audio API带来的视听盛宴
话说HTML5的炫酷真的是让我爱不释手,即使在这个提到IE就伤心不完的年代.但话又说回来,追求卓越Web创造更美世界这样高的追求什么时候又与IE沾过边儿呢?所以当你在看本文并且我们开始讨论HTML5等 ...
- jQuery1.9.1源码分析--数据缓存Data模块
jQuery1.9.1源码分析--数据缓存Data模块 阅读目录 jQuery API中Data的基本使用方法介绍 jQuery.acceptData(elem)源码分析 jQuery.data(el ...
- 百度统计API的使用
百度统计API的使用 在搭建自己博客的时候,希望自己能有个日志系统,能够看到PV.UV等信息,同时自己也搭建了个ELK系统,可惜服务器配置太低(1GHZ+1G内存),根本运行不起来.只能使用第三方的日 ...
- HTML5 History API让ajax能回退到上一页
HTML5 History API提供了一种功能,能让开发人员在不刷新整个页面的情况下修改站点的URL.这个功能很有用,例如通过一段JavaScript代码局部加载页面的内容,你希望通过改变当前页面的 ...
- window.history的跳转实质-HTML5 history API 解析
在上一浏览器跳转行为的测试中,我们看到了通过不同的方法操作浏览器跳转时,它的刷新表现有所不同,在这一文章中,将看看,为何会产生这样的不同?其背后的实质是什么?浏览器的访问历史记录到底是如何运作的呢? ...
- HTML5与后台服务器的数据流动问题
编辑中,尚未完稿...2017.7.14 1345 很多前端开发出来的HTML5可能对于后台开发者来说,并不是很清楚,也许像我一样一知半解.而且真的让人很糊涂的地方就是前端的JS如何与后端的数据库进行 ...
随机推荐
- CVE-2018-4407 漏洞复现POC
pip install scapy import scapy from scapy.all import * send(IP(dst="192.168.1.132",options ...
- TCP端口复用引发的异常,用setsockopt来解决
TCP端口复用引发的异常,用setsockopt来解决 我们在并发连接一个服务端时候他会出现这种情况 OSError: [WinError 10048] 通常每个套接字地址(协议/网络地址/端口)只允 ...
- Spring cloud搭建Eureka高可用注册中心
注册中心在微服务中是必不可少的一部分,主要用来实现服务自治的功能,本文则主要记载使用Netflix提供的Eureka作为注册中心,来实现服务自治的功能. 实际上Eureka的集群搭建方法很简单:每一台 ...
- 《VR入门系列教程》之2---VR头显
什么是虚拟现实? 虚拟现实的目标:让人们相信真实地处于一个虚拟世界中.要达到这个目标就得让人们的大脑(负责视觉和运动感知部分)欺骗他们.不同技术合在一起才可以创造这种幻觉,包括: 全立 ...
- python中if __name__ == '__main__' :main(()
例如: if __name__ == '__main__': main() 如果运行的是主函数的话,执行下一句main() 如果作为模块被其他文件导入使用的话,我们就不执行后面的main()什么的. ...
- TIJ读书笔记-第21章-并发
一本Think in java,从去年6月份开始读,读了快一年了,也快读完了,然而回头想想,却好像什么也不记得了,好记性不如烂笔头,那就从现在开始记录一下吧.由于现在在读的是并发,那就先从这章开始吧. ...
- 【Android】Android sdk content loader 0%
前天用 Eclipse 突然遇到了这个问题...重启了好几次都不行,百度了一下,原来之前有不少人遇到过.后来找到了一篇文章,其中的方法二(如下): 方法二(关闭后,拔网线再重启): 如果用最省事的方法 ...
- python 处理json数据
python 处理 json数据 以下是登录账号后获取的json数据,headers中注意加入cookie值 需要处理的数据如下: 全部代码如下 #!/usr/bin/env python # -*- ...
- 如何确定FPGA电路中DDR4的Speed bin 是否兼容?
原创 by DeeZeng DDR4 是否兼容,拿更快速度的DDR4,是否可以不改FPGA工程,直接换料就能直接用? 实际工作中,经常会碰到因为DDR3/4 或其他料件换料了,需要判断FPGA工程中I ...
- Task CancellationTokenSource和Task.WhenAll的应用
Task是.net4.0推出的异步编程类,与ThreadPool.QueneUserWorkItem方法类似的是,Task也是使用线程池来工作的.但Task比起这个QueneUserWorkItem的 ...