平台全称:助睿数智(Uniplore)一站式数据科学实验平台
平台定位:覆盖数据接入、ETL处理、机器学习建模到可视化分析的全链路Agentic零代码数据智能
产品官网:https://www.uniplore.com/
实验平台地址:https://lab.guilian.cn/
1. 实验目的
- 数据加工能力培养:掌握半结构化日志数据的解析、字段拆分与规整方法,将原始文本日志转化为标准结构化数据表。
- 指标体系搭建:通过多维度数据聚合、字段衍生与跨表关联,构建适配浏览器市场与用户行为分析场景的指标体系。
- 业务分析实战:基于真实用户行为数据,完成浏览器市场格局、用户使用习惯等核心业务问题的初步探查。
2. 实验环境
- 实验平台:助睿在线实验平台(https://lab.guilian.cn/)
- 数据科学平台:助睿数智(Uniplore)一站式数据科学平台,覆盖数据接入、ETL处理、机器学习建模到可视化展示的全链路零代码功能
- 数据处理工具:助睿 ETL 数据集成平台
- 数据规模:1000名用户,800万+条行为记录,原始数据约825MB
3. 实验数据与建模思路
3.1 数据构成
本实验基于首届中国互联网数据挖掘竞赛公开数据集,是典型的计算机用户行为半结构化日志数据。数据集包含三大核心部分:
数据覆盖1000名用户连续4周的电脑使用行为,每周抽取一周数据,时间跨度为4个月。
3.2 核心数据模型与加工思路
- 原始数据特点:数据以TXT文本文件形式存在,文件名包含用户ID、日期和开机时间,文件内部结构为“键值对”形式的半结构化日志
- 加工思路:通过“获取文件名”组件批量定位日志文件,使用自定义“Java代码”组件解析文件名与文件内容,将半结构化数据拆解为行列清晰的结构化表(behavior_events),并通过ETL流程进行清洗、聚合与衍生
- 分析思路:对行为数据按进程名统计用户覆盖度,发现浏览器类应用具有最高覆盖率,且包含url字段,具备深度分析价值。因此,后续分析将锁定浏览器,分析市场格局、用户使用时段等
4. 实验步骤
本实验主要分为三大阶段:
4.1 数据准备与结构化转换
创建项目,命名为互联网用户行为日志数据加工

4.1.1 数据资源获取与建表
进入项目,在文件库的根目录下右键新建文件夹,命名为互联网用户行为日志数据集

点击公共空间,找到数据资源标签,点击更多,选择导入,将其中标签为“互联网用户行为日志数据集“的20个样例csv日志文件(实际只有12个,其他的是重复的)导入到已创建的“互联网用户行为日志数据集”目录下


连接数据库,(就是前几次实验连接的团队私有数据库此处不做演示)
为确保数据结构化后有处存放,首先在资源库标签根目录右键创建转换流命名为“创建原始行为日志数据表”,拖入执行一个SQL脚本组件来创建明细表 behavior_events

具体sql脚本如下:
CREATE TABLE behavior_events (
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '自增主键',
session_id VARCHAR(255) COMMENT '会话唯一ID',
user_id VARCHAR(100) COMMENT '用户ID',
session_start_time VARCHAR(50) COMMENT '会话开始时间',
event_seconds INT COMMENT '事件发生秒数',
process_name VARCHAR(255) COMMENT '进程名称',
process_id VARCHAR(100) COMMENT '进程ID',
url TEXT COMMENT '访问网址',
addr_handle VARCHAR(255) COMMENT '地址栏句柄',
tab_handle VARCHAR(255) COMMENT '标签页句柄',
browser_version VARCHAR(100) COMMENT '浏览器版本',
window_handle VARCHAR(255) COMMENT '窗口句柄',
app_name VARCHAR(255) COMMENT '程序名称',
company_name VARCHAR(255) COMMENT '开发公司',
source_file VARCHAR(255) COMMENT '原始日志文件名',
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '入库时间',
INDEX idx_session_id (session_id),
INDEX idx_user_id (user_id)
) COMMENT '用户行为事件明细表';
配置完成后执行转换流

4.1.2 日志文件批量采集与解析
新建转换流“行为日志数据转为结构化数据”,拖拽“获取文件名”组件,双击进入配置,点击浏览文件,选择文件库创建的“互联网用户行为日志数据集”文件夹后点击确认,然后再点击增加,再点击确认


4.1.3 Java代码实现半结构化解析
拖拽“Java代码”组件,并将其与“获取文件名”组件相连,选择主输出步骤;在组件中编写Java逻辑,实现以下核心功能:

Java代码如下:
// 全局变量定义
String pathField;
String shortFilenameField;
public boolean processRow() throws HopException {
if (first) {
pathField = "filename";
shortFilenameField = "short_filename";
first = false;
}
Object[] r = getRow();
if (r == null) {
setOutputDone();
return false;
}
String path = get(Fields.In, pathField).getString(r);
String short_filename = get(Fields.In, shortFilenameField).getString(r);
String user_id = "";
String l_start = "";
if (short_filename != null) {
String name = short_filename.replace(".txt", "");
String[] parts = name.split("_");
if (parts.length >= 3) {
user_id = parts[0];
l_start = parts[1] + " " + parts[2].replace("-", ":");
}
}
String session_id = user_id + "_" + l_start;
java.io.BufferedReader br = null;
try {
br = new java.io.BufferedReader(new java.io.FileReader(path));
String line = "";
// 跳过前两行(Last和L_Start)
br.readLine();
br.readLine();
while ((line = br.readLine()) != null) {
if (line.trim().isEmpty()) {
continue;
}
// 解析键值对
String[] kvPairs = line.split("\\\\[=\\\\]");
String t = "";
String p = "";
String i = "";
String u = "";
String a = "";
String b = "";
String v = "";
String w = "";
String n = "";
String c = "";
for (String kv : kvPairs) {
int sepIdx = kv.indexOf("<=>");
if (sepIdx == -1) {
continue;
}
String key = kv.substring(0, sepIdx).trim();
String val = kv.substring(sepIdx + 3);
if ("T".equals(key)) {
t = val;
} else if ("P".equals(key)) {
p = val;
} else if ("I".equals(key)) {
i = val;
} else if ("U".equals(key)) {
u = val;
} else if ("A".equals(key)) {
a = val;
} else if ("B".equals(key)) {
b = val;
} else if ("V".equals(key)) {
v = val;
} else if ("W".equals(key)) {
w = val;
} else if ("N".equals(key)) {
n = val;
} else if ("C".equals(key)) {
c = val;
}
}
// 创建输出行
Object[] outRow = createOutputRow(r, data.outputRowMeta.size());
get(Fields.Out, "session_id").setValue(outRow, session_id);
get(Fields.Out, "user_id").setValue(outRow, user_id);
get(Fields.Out, "l_start").setValue(outRow, l_start);
get(Fields.Out, "t").setValue(outRow, t);
get(Fields.Out, "p").setValue(outRow, p);
get(Fields.Out, "i").setValue(outRow, i);
get(Fields.Out, "u").setValue(outRow, u);
get(Fields.Out, "a").setValue(outRow, a);
get(Fields.Out, "b").setValue(outRow, b);
get(Fields.Out, "v").setValue(outRow, v);
get(Fields.Out, "w").setValue(outRow, w);
get(Fields.Out, "n").setValue(outRow, n);
get(Fields.Out, "c").setValue(outRow, c);
get(Fields.Out, "source_file").setValue(outRow, short_filename);
putRow(data.outputRowMeta, outRow);
}
} catch (Exception e) {
logError(e.getMessage(), e);
} finally {
try {
if (br != null) {
br.close();
}
} catch (Exception e) {
// ignore
}
}
return true;
}
在下方字段空白处右键插入

插入字段参考如下
|
字段名 |
类型 |
|
session_id |
String |
|
user_id |
String |
|
l_start |
String |
|
t |
String |
|
p |
String |
|
i |
String |
|
u |
String |
|
a |
String |
|
b |
String |
|
v |
String |
|
w |
String |
|
n |
String |
|
c |
String |
|
source_file |
String |
点击确认后右键选择显示输出字段,查看输出是否符合预期

4.1.4 字段筛选与表输出



在数据库字段处右键获取字段,表字段从session_id开始,按顺序向下填入


4.2 数据分析方向确定
新建转换流,命名为“创建进程统计表”
拖入执行一个sql脚本组件

具体sql脚本如下:
— 创建程序/软件统计表
CREATE TABLE program_stats (
program_name VARCHAR(255) NOT NULL, — 程序/软件名称
user_count INT NOT NULL — 使用用户数
);
由于数据量较大,为了顺利运行转换流,运行转换流前,先右键团队私有数据库,勾选使用结果流

为确定最具分析潜力的对象,新建转换流“统计进程用户规模”:


双击“替换NULL值”组件,勾选“选择字段”,在下方字段表格中插入一行,并输入:
字段:process_name
值替换为:未知
是否为空:否






进入助睿BI,点击数据集,选择新建数据集

将刚刚创建的program_stats拖入画布

字段配置如下

保存并发布
点击工作表,新建工作表

选择水平条图,配置如下

User_count选择降序

4.3 数据清洗、聚合与关联加工
根据分析目标,预先设计了browser_coverage(市场格局表)和browser_hourly(时段统计表)的结构,并创建了相应的数据库表。

sql脚本如下:
CREATE TABLE `browser_coverage` (
`browser_name` VARCHAR(50) NOT NULL COMMENT '浏览器进程名',
`user_count` INT NOT NULL COMMENT '使用用户数(去重)',
`total_duration_sec` BIGINT NOT NULL COMMENT '总使用时长(秒)'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='浏览器用户覆盖率与总时长';

sql脚本如下:
CREATE TABLE `browser_hourly` (
`browser_name` VARCHAR(50) NOT NULL COMMENT '浏览器进程名',
`hour` TINYINT NOT NULL COMMENT '小时(0-23)',
`active_user_count` INT NOT NULL COMMENT '活跃用户数',
PRIMARY KEY (`browser_name`, `hour`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='浏览器按小时活跃用户数';
随后,新建转换流“互联网用户行为日志数据清洗抽取”,核心步骤如下:




- 排序:按session_id和event_seconds升序排序

-
- 分析查询:获取同一会话内下一条记录的event_seconds值,存入新字段next_event_seconds

-
- 计算器:通过公式 next_event_seconds – event_seconds 计算得出用户在每个窗口的停留时长 duration_sec,并过滤掉时长无效(≤0)的记录

使用“字段选择”,只保留 user_id, process_name, session_start_time, url, duration_sec

使用“过滤记录”组件,过滤掉 duration_sec <= 0 的记录(最后一条记录没有下一条,时长无效,忽略)

后续很多分析需要按天、按时段聚合(比如每日使用时长、时段热力图)。提前提取好日期和小时,后续分组时直接使用,避免重复解析。
session_start_time 的格式为:yyyy-MM-dd HH:mm:ss,通过剪切字符串组件可以直接获取yyyy-MM-dd

目前获取的数据中,session_start_time 的类型为String,为方便提前提取好小时,需要将session_start_time 的类型设置为Date,格式为yyyy-MM-dd HH:mm:ss




到这一步,大体组件连线如下:





拖入排序记录组件,将分组组件与其连接,选择复制发送





分支B:

总体连线如下:

运行转换流完毕后,右键团队私有数据库选择加载元数据,在数据探查中可以看到输出结果


5. 实验总结
本次实验基于海量真实的用户行为日志,成功完成了一次完整的数据加工与分析流程,实现了以下目标:

