package cn.wust.com.demo.weblog.clickstream;
import cn.wust.com.demo.mrbean.WebLogBean;
import cn.wust.com.demo.utils.DateUtil;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
import java.io.IOException;
import java.net.URI;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
public class ClickStreamPageView extends Configured implements Tool {
@Override
public int run(String[] strings) throws Exception {
Configuration conf = super.getConf();
Job job = Job.getInstance(conf);
job.setJarByClass(ClickStreamPageView.class);
String inputPath = "hdfs://hadoop01:9000/weblog/"+ DateUtil.getYestDate()+"/weblogPreOut";
String outputPath = "hdfs://hadoop01:9000/weblog/"+DateUtil.getYestDate()+"/pageViewOut";
FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop01:9000"), conf,"root");
if(fileSystem.exists(new Path(outputPath))){
fileSystem.delete(new Path(outputPath),true);
}
fileSystem.close();
job.setInputFormatClass(TextInputFormat.class);
job.setOutputFormatClass(TextOutputFormat.class);
FileInputFormat.setInputPaths(job,new Path(inputPath));
FileOutputFormat.setOutputPath(job,new Path(outputPath));
job.setMapperClass(ClickStreamMapper.class);
job.setReducerClass(ClickStreamReducer.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(WebLogBean.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);
boolean b = job.waitForCompletion(true);
return b?0:1;
}
static class ClickStreamMapper extends Mapper<LongWritable,Text,Text,WebLogBean>{
Text k = new Text();
WebLogBean v = new WebLogBean();
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String line = value.toString();
String[] fields = line.split("\001");
if(fields.length<9) return;
//将切分出来的各字段set到weblogbean中
v.set("true".equals(fields[0])?true:false,fields[1],fields[2],fields[3],fields[4],fields[5],fields[6],fields[7],fields[8]);
//只有有效记录才进入后续处理
if(v.isValid()){
//此处用ip地址来标记用户
k.set(v.getRemote_addr());
context.write(k,v);
}
}
}
static class ClickStreamReducer extends Reducer<Text,WebLogBean, NullWritable,Text>{
Text v = new Text();
/*
192.168.174.32 </w>www.baidu.com 12:00, /www.baidu.com 12.20
*/
//key:ip
@Override
protected void reduce(Text key, Iterable<WebLogBean> values, Context context) throws IOException, InterruptedException {
ArrayList<WebLogBean> beans = new ArrayList<WebLogBean>();
//先将一个用户的所有访问记录中的时间拿出来排序
for (WebLogBean bean : values) {
//为什么List集合当中不能直接添加循环出来的这个bean?
//这里通过属性拷贝,每次new一个对象,避免了bean的属性值每次覆盖
WebLogBean webLogBean = new WebLogBean();
try {
BeanUtils.copyProperties(webLogBean, bean);
} catch (Exception e) {
e.printStackTrace();
}
beans.add(webLogBean);
}
//将bean按时间先后顺序排序
Collections.sort(beans, new Comparator<WebLogBean>() {
@Override
public int compare(WebLogBean o1, WebLogBean o2) {
try {
Date d1 = toDate(o1.getTime_local());
Date d2 = toDate(o2.getTime_local());
if (d1 == null || d2 == null)
return 0;
return d1.compareTo(d2); //2018-12-23 12:32:46 -->30053835859898
} catch (ParseException e) {
e.printStackTrace();
return 0;
}
}
});
/***
* 以下逻辑为:从有序bean中分辨出各次visit,并对一次visit中所访问的page按顺序标号step
* 核心思想:
* 就是比较相邻两条记录中的时间差,如果时间差<30min,则该两条记录属于同一个session
* 否则,就属于不同的session
*/
int step = 1;
String session = UUID.randomUUID().toString();
for (int i = 0; i < beans.size(); i++) {
WebLogBean bean = beans.get(i);
//如果仅有3条数据,则直接输出
if (1 == beans.size()) {
//设置默认停留时长为60s
v.set(session + "\001" + key.toString() + "\001" + bean.getRemote_user() + "\001" + bean.getTime_local()
+ "\001" + bean.getRequest() + "\001" + step + "\001" + (60) + "\001" + bean.getHttp_referer() + "\001"
+ bean.getHttp_user_agent() + "\001" + bean.getBody_bytes_sent() + "\001" + bean.getStatus());
context.write(NullWritable.get(), v);
session = UUID.randomUUID().toString();
break;
}
//如果不止一条数据,则将第一条数据跳过不输出,遍历第二条时再输出
if (i == 0) {
continue;
}
//求近两次时间差
long timeDiff = 0;
try {
timeDiff = timeDiff(toDate(bean.getTime_local()), toDate(beans.get(i - 1).getTime_local()));
} catch (ParseException e) {
e.printStackTrace();
}
//如果本次-上次时间差<30min,则输出前一次的页面访问信息
if (timeDiff < 30 * 60 * 1000) {
v.set(session + "\001" + key.toString() + "\001" + beans.get(i - 1).getRemote_user() + "\001" + beans.get(i - 1).getTime_local() + "\001"
+ beans.get(i - 1).getRequest() + "\001" + step + "\001" + (timeDiff / 1000) + "\001" + beans.get(i - 1).getHttp_referer() + "\001"
+ beans.get(i - 1).getHttp_user_agent() + "\001" + beans.get(i - 1).getBody_bytes_sent() + "\001"
+ beans.get(i - 1).getStatus());
context.write(NullWritable.get(), v);
step++;
} else {
//如果本次-上次时间差>30min,则输出前一次的页面访问信息且将step重置,以分隔为新的visit
v.set(session + "\001" + key.toString() + "\001" + beans.get(i - 1).getRemote_user() + "\001" + beans.get(i - 1).getTime_local() + "\001"
+ beans.get(i - 1).getRequest() + "\001" + step + "\001" + (60) + "\001" + beans.get(i - 1).getHttp
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
基于hadoop 的购物网站日志分析系统源代码(期末大作业&课程设计),含有代码注释,满分大作业资源,新手也可看懂,期末大作业、课程设计、高分必看,下载下来,简单部署,就可以使用。该项目可以作为课程设计期末大作业使用,该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。 基于hadoop 的购物网站日志分析系统源代码(期末大作业&课程设计),含有代码注释,满分大作业资源,新手也可看懂,期末大作业、课程设计、高分必看,下载下来,简单部署,就可以使用。该项目可以作为课程设计期末大作业使用,该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。 基于hadoop 的购物网站日志分析系统源代码(期末大作业&课程设计),含有代码注释,满分大作业资源,新手也可看懂,期末大作业、课程设计、高分必看,下载下来,简单部署,就可以使用。该项目可以作为课程设计期末大作业使用,该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。基于hadoop 的购物网站日志分析系统源代码(期末大作业&课程设计),含有代码注释,满分大作业资
资源推荐
资源详情
资源评论
收起资源包目录
基于hadoop 的购物网站日志分析系统+源代码+文档说明.zip (70个子文件)
文件夹main
mvnw.cmd 6KB
pom.xml 5KB
网站日志分析.zip 2.28MB
src
test
java
cn
wust
com
demo
DemoApplicationTests.java 215B
main
resources
lib
lombok.jar 1.83MB
application.properties 1KB
css
iconfont.css 3KB
app.css 23KB
login_Home_Welcome.css 3KB
order_Reports.css 3KB
index.css 241KB
chunk.css 1KB
log4j.properties 1KB
images
header_border_dark.png 8KB
购物车满.png 5KB
avatar.png 7KB
qiehuan_dark.png 1KB
static
reports.js 15KB
echarts.min.js 951KB
index.js 13KB
drillDown.js 2KB
jquery-3.5.1.min.js 87KB
fonts
iconfont.ttf 2KB
iconfont.woff2 1KB
iconfont.svg 6KB
iconfont.eot 3KB
iconfont.woff 2KB
java
cn
wust
com
demo
DemoApplication.java 406B
mapper
UserBehaviorMapper.java 5KB
weblog
clickstream
ClickStreamPageView.java 10KB
ClickStreamVisit.java 5KB
controller
HelloController.java 4KB
utils
DBUtils.java 2KB
IPUtil.java 2KB
DateUtil.java 584B
AddressUtils.java 8KB
mrbean
UserBehaviorBean.java 3KB
VisitBean.java 3KB
PageViewsBean.java 3KB
WebLogBean.java 4KB
test.java 981B
pojo
selltopcatPojo.java 125B
UserHourPojo.java 172B
AgainRatePojo.java 143B
HotPageTop10.java 118B
UserRatePojo.java 320B
Result.java 953B
ConvertRatePojo.java 422B
PvsEveryhour.java 145B
ReturningTop10.java 132B
UserHabitPojo.java 476B
FlowNumPojo.java 137B
selltopitemPojo.java 127B
FlowReturnPojo.java 322B
UserBehaviorPojo.java 1KB
IpEveryhour.java 125B
UserFlowPojo.java 161B
pre
WeblogPreProcess.java 4KB
UserBehaviorPreProcess.java 4KB
WeblogPreVaild.java 63B
WeblogParser.java 2KB
service
UserBehaviorService.java 783B
UserBehaviorServiceImpl.java 2KB
webapp
WEB-INF
jsp
reports.jsp 25KB
index.jsp 8KB
.mvn
wrapper
maven-wrapper.properties 218B
maven-wrapper.jar 50KB
MavenWrapperDownloader.java 5KB
mvnw 10KB
.gitignore 395B
共 70 条
- 1
资源评论
yava_free
- 粉丝: 2653
- 资源: 754
下载权益
C知道特权
VIP文章
课程特权
开通VIP
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功