随着最近几年旅游行业的兴起,越来越多的景区景点将传统模式的线下统计模式变更成为了线上分析统计模式,线上对景区游客数据的管理与监督的新型模式。很多的景点采用游客数据分析平台系统,在线上对不同景点内部的游客数据进行管理,对景区各部门的员工进行管理,实现游客旅游数据分析的数字化,一体化。
本次毕业设计景点游客数据分析平台,采用springboot、springcloud,hadoop,hbase,es等技术结合前后端分离模式的架构搭建,系统架构层面非常的稳定,支持多用户模式的同时登录在线处理业务。实现了不同地区各类景点对用户实时动态的掌控,满足景区管理者的分析需求。
原文地址
一、程序设计
本次基于大数据架构的景点游客数据分析平台主要内容涉及:
主要功能模块:用户登录、人员管理、部门管理、角色管理、游客流量统计模块、大数据可视化模块,游客数据管理模块等
主要包含技术:java,hadoop,hbase,es,Mysql,Springboot,MyBatis,javascript,html,css等
主要包含算法及方法:Kmeans数据聚类算法
二、效果实现
系统登录
游客数据
趋势分布
大数据分析
其他效果省略
三、数据采集设计
本次毕设系统在景点游客数据采集设计中,主要采用java JSOUP Chromdriver结合的方式,其中JSOUP 方式主要获取全国各大景区的网站地址,chromedriver用于模拟用户请求获取景点游客的实时数据,不断提高优化提高景点游客数据的采集精准度。
采集算法实现
部分核心算法代码
代码语言:java复制 /**
* 景点数据采集
*/
@Scheduled(fixedDelay = 1000 * 60 * 1)
public void jingdianResTask() {
if (!detailOpen) return;
Date start = new Date();
log.info("采集任务开始:{}", start);
try {
String querySql = "select id,url from t_jingdian_res where deal=0 limit 1000;";
List<Map<String, Object>> oplogs = jdbcTemplate.queryForList(querySql);
if (CollectionUtils.isEmpty(oplogs)) {
log.info("任务结束,暂无企业责任数据处理");
return;
}
List<List<Map<String, Object>>> lists = ListCF.subList(oplogs, 1000);
CountDownLatch latch = new CountDownLatch(lists.size());
for (List<Map<String, Object>> sublist : lists) {
CompletableFuture.runAsync(() -> {
sublist.forEach(task -> {
Integer id = Integer.valueOf(String.valueOf(task.get("id")));
String url = String.valueOf(task.get("url"));
try {
Document doc = null;
for (int p = 0; p < 3; p ) {
try {
doc = Jsoup.connect(url).ignoreContentType(true).ignoreHttpErrors(true).timeout(5000).get();
if (null != doc) break;
} catch (Exception e) {
e.printStackTrace();
log.error("地址:{},打开失败,重试次数:{}", url, p);
}
}
if (null == doc) return;
String gdzr_mx = doc.select("body > div.wrap > div.article.w680 > div:nth-child(2)").text();
String ygzr_mx = doc.select("body > div.wrap > div.article.w680 > div:nth-child(3)").text();
String gkzzr_mx = doc.select("body > div.wrap > div.article.w680 > div:nth-child(4)").text();
String hjzr_mx = doc.select("body > div.wrap > div.article.w680 > div:nth-child(5)").text();
String shzr_mx = doc.select("body > div.wrap > div.article.w680 > div:nth-child(6)").text();
String shzr_img = doc.select("body > div.wrap > div.article.w680 > div.chart > div > img").attr("abs:src");
if (StringUtils.isEmpty(gdzr_mx) && StringUtils.isEmpty(ygzr_mx) && StringUtils.isEmpty(gkzzr_mx) && StringUtils.isEmpty(hjzr_mx) && StringUtils.isEmpty(shzr_mx) && StringUtils.isEmpty(shzr_img))
return;
String sql = "UPDATE `yk_data_view`.`t_jingdian_res` SET `gdzr_mx`=?, `ygzr_mx`=?, `gkxzr_mx`=?, `hjzr_mx`=?, `shzr_mx`=?, `shzr_img`=?, `deal`='1',`update_time`=NOW() WHERE `id`=?;";
jdbcTemplate.update(sql, gdzr_mx, ygzr_mx, gkzzr_mx, hjzr_mx, shzr_mx, shzr_img, id);
log.info("地址:{},爬取成功", url);
} catch (Exception e) {
e.printStackTrace();
log.error("地址:{},爬取失败", url);
}
});
latch.countDown();
}, executorPool);
}
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
Date end = new Date();
log.info("任务结束,耗时:{}ms,数量:{}", (end.getTime() - start.getTime()), oplogs.size());
} catch (Exception e) {
e.printStackTrace();
log.error("任务错误,错误信息:{}", e.getCause());
}
}