基于java 生成打车网约车订单测试数据
背景
该需求在笔者本科的毕业设计过程中产生,需要生成一定量的数据用于聚类分析测试数据集。
笔者经过大量的搜索,依然没有找到能符合项目需要的数据集,最终决定通过代码的方式生成若干订单数据。为了方便其他人查看,笔者将查询到的数据集统一放在这里。
滴滴盖亚数据 | https://outreach.didichuxing.com/ | 需要申请 | |
UberMovement | https://link.zhihu.com/?target=https%3A//movement.uber.com/ | 国际网约车巨头,笔者需要国内的数据,pass | |
阿里天池数据集 | https://tianchi.aliyun.com/dataset?spm=5176.14154004.J_3941670930.21.31fe5699J4PqSP | 可以搜索到滴滴公布的数据,搜索关键字”滴滴“ | |
知乎作者总结 | https://www.zhihu.com/question/24335537 | 比较全面 |
尽管存在诸多真实的数据集,但都不满足笔者做聚类分析的基本需求,其中最有可能满足的是2020_ccf滴滴时空预测_训练数据集,但是数据没有任何描述信息,直接从数据入手无法理解。
基本目标数据
字段 | 类型 |
订单开始时间 | DATE |
订单结束时间 | DATE |
起点(经纬度) | VARCHAR |
终点(经纬度) | VARCHAR |
成果截图
![]() |
![]() |
![]() |
![]() |
![]() |
代码实现
地点选择
为了尽可能保证数据真实性,作为打车地点应该选择为该城市热门地点。以哈尔滨为例,通过美团进行搜索,结果即可认为是该城市热门地点。
- 抓包找到数据请求路径
curl "https://apimobile.meituan.com/group/v4/poi/pcsearch/105?uuid=6961927388a74eba9ec9.1652337967.1.0.0&userid=1699913514&limit=32&offset=32&cateId=-1&q=^%^E5^%^93^%^88^%^E5^%^B0^%^94^%^E6^%^BB^%^A8&token=Im7ycrPXlIs7yI8TXXXXXXXXXXXX-H "Accept: */*" ^-H "Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6" ^-H "Connection: keep-alive" ^-H "Cookie: uuid=6961927388a74eXXXXXXXXXXXXXXXXXXXXX-H "Origin: https://hrb.meituan.com" ^-H "Referer: https://hrb.meituan.com/" ^-H "Sec-Fetch-Dest: empty" ^-H "Sec-Fetch-Mode: cors" ^-H "Sec-Fetch-Site: same-site" ^-H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.41 Safari/537.36" ^-H "sec-ch-ua: ^\^" Not A;Brand^\^";v=^\^"99^\^", ^\^"Chromium^\^";v=^\^"101^\^", ^\^"Microsoft Edge^\^";v=^\^"101^\^"" ^-H "sec-ch-ua-mobile: ?0" ^-H "sec-ch-ua-platform: ^\^"Windows^\^"" ^--compressed
发现请求通过设置offset 参数为分页查询limit 偏移量,所以可以通过设置该值(0,32,64,96,···)完成对全部数据的查询。如上图抓包数据所示
- 通过postman 将浏览器抓的包导入并转换成java代码,如上图postman转java代码所示
// 执行抓包代码
package com.example.point.predict;import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.example.point.domain.mapper.HotAreaDao;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.io.IOException;
import java.util.ArrayList;
import java.util.List;@Service
public class ExecutorTask {// hotAreaDao 基于HotArea 的持久层接口,使用MP框架,继承BaseMapper接口@Autowiredprivate HotAreaDao hotAreaDao;public void getHotArea() {int index = 0;while (index++ <= 36) {List<HotArea> list = doGetHotArea(String.valueOf(32 * index));assert list != null;// 持久化到数据库中list.forEach(a -> hotAreaDao.insert(a));}}private List<HotArea> doGetHotArea(String offset) {HttpUrl url = HttpUrl.parse("https://apimobile.meituan.com/group/v4/poi/pcsearch/105?uuid=6961927388a74eba9ec9.1652337967.1.0.0&userid=1699913514&limit=32&cateId=-1&q=%E5%93%88%E5%B0%94%E6%BB%A8&token=Im7ycrPXlIs7yI8TnP3eLq2MH8UAAAAAuxEAALrOIZCcFyKVfLB6YYHG4mtoojKPoeQebjDm6R80cgwPID2K83VeJZ9-A9VoUDwc5A&sort=default").newBuilder().addQueryParameter("offset", offset).build();OkHttpClient client = new OkHttpClient().newBuilder().build();Request request = new Request.Builder().url(url).method("GET", null).addHeader("Accept", "*/*").addHeader("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6").addHeader("Connection", "keep-alive").addHeader("Cookie", "uuid=6961927388a74eba9ec9.1652337967.1.0.0; _lx_utm=utm_source%3Dbing%26utm_medium%3Dorganic; _lxsdk_cuid=180b70485d4c8-06c7b6d70175c7-12333272-e1000-180b70485d4c8; ci=105; mtcdn=K; userTicket=SULzbnlKOnLeJcncXywbuPQZSqyBbqEFvtOYsQMx; _yoda_verify_resp=1ovN6a48LK40Lon%2BFF2pB9OP9nhfGcUiJEjzL%2FSrhFyDao4sU7K4toyhPpT3WnmWNj4%2Fm3M87qwvZTfv7fQw96fksSiW6OR94P6rXB7RfTPoRCGBxUrRev%2FrWv0OEWQDzuRKsp%2BWhmKlKKSF2gbVhiU%2FxcSaAtH26KdlwUPotsQB4lkYvduG3ofYO%2BhRkTMEJaSoGgqwO6uf%2B0v2NB6vVQZkWD5JJK0pSx2CEZcb0%2FnEWywKHKD7gCvRw2FbrBvZPEVxsCfq8H71Gzd7NwMr7NI%2BvcjfU345F9tN%2FAJHl8GAOQ%2FfrJgjcloer1ET3X%2FeVepex3txcxkzjPbHt4tixqcn%2F8jXHHhXMrkluYWfW6E7%2BoBNyoHMScijYJmDr3EH; _yoda_verify_rid=15289e4b3a40b014; u=1699913514; n=ccr763202343; lt=Im7ycrPXlIs7yI8TnP3eLq2MH8UAAAAAuxEAALrOIZCcFyKVfLB6YYHG4mtoojKPoeQebjDm6R80cgwPID2K83VeJZ9-A9VoUDwc5A; mt_c_token=Im7ycrPXlIs7yI8TnP3eLq2MH8UAAAAAuxEAALrOIZCcFyKVfLB6YYHG4mtoojKPoeQebjDm6R80cgwPID2K83VeJZ9-A9VoUDwc5A; token=Im7ycrPXlIs7yI8TnP3eLq2MH8UAAAAAuxEAALrOIZCcFyKVfLB6YYHG4mtoojKPoeQebjDm6R80cgwPID2K83VeJZ9-A9VoUDwc5A; token2=Im7ycrPXlIs7yI8TnP3eLq2MH8UAAAAAuxEAALrOIZCcFyKVfLB6YYHG4mtoojKPoeQebjDm6R80cgwPID2K83VeJZ9-A9VoUDwc5A; unc=ccr763202343; firstTime=1652338204933; _lxsdk_s=180b70485d5-ced-43f-b8c%7C%7C129").addHeader("Origin", "https://hrb.meituan.com").addHeader("Referer", "https://hrb.meituan.com/").addHeader("Sec-Fetch-Dest", "empty").addHeader("Sec-Fetch-Mode", "cors").addHeader("Sec-Fetch-Site", "same-site").addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.41 Safari/537.36").addHeader("sec-ch-ua", "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"101\", \"Microsoft Edge\";v=\"101\"").addHeader("sec-ch-ua-mobile", "?0").addHeader("sec-ch-ua-platform", "\"Windows\"").build();try {Response response = client.newCall(request).execute();String json = response.body().string();JSONObject jsonObject = JSONObject.parseObject(json).getJSONObject("data");List<HotArea> list = new ArrayList<>();JSONArray array = jsonObject.getJSONArray("searchResult");for (int i = 0; i < array.size(); i++) {JSONObject item = array.getJSONObject(i);HotArea hotArea = new HotArea.HotAreaBuilder().city("哈尔滨").sourceId(73856242).title(item.getString("title")).latitude(item.getString("latitude")).longitude(item.getString("longitude")).showtype(item.getString("showType")).backcatename(item.getString("backCateName")).areaname(item.getString("areaname")).originJson(item.toJSONString()).img(item.getString("imageUrl")).build();list.add(hotArea);}return list;} catch (IOException e) {e.printStackTrace();}return null;}}
// HotArea 实体类,也就是具体将美团上获取的 所需要的数据封装成类
package com.example.point.predict;import java.io.Serializable;import com.baomidou.mybatisplus.annotation.TableId;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;/*** hot_area* @author */
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class HotArea implements Serializable {/*** 主键id*/@TableIdprivate Integer id;/*** 城市*/private String city;/*** 源id*/private Integer sourceId;private String title;/*** 经度*/private String latitude;/*** 维度*/private String longitude;/*** 地点类型(学校、景点···)*/private String showtype;private String backcatename;/*** ___路(学府路,和平路···)*/private String areaname;/*** 原始json*/private String originJson;private String img;private static final long serialVersionUID = 1L;
}
// HotArea 的数据持久化接口,xml不再粘贴
package com.example.point.domain.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.point.predict.HotArea;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface HotAreaDao extends BaseMapper<HotArea> {int deleteByPrimaryKey(Integer id);int insert(HotArea record);int insertSelective(HotArea record);HotArea selectByPrimaryKey(Integer id);int updateByPrimaryKeySelective(HotArea record);int updateByPrimaryKey(HotArea record);
}
通过创建一个Test 方法,执行ExecutorTask的getHotArea 方法即可得到热点地区信息。如上图热点地区数据所示.
- 生成测试订单数据集
订单数据表
字段名 | 类型 | 描述信息 |
or_id | bigint | 主键id |
orgin | varchar | 起点 |
destination | varchar | 终点 |
begin_time | datetime | 开始时间 |
endtime | datetime | 结束时间 |
node | varchar | 备注信息 |
cost | double | 费用 |
client_id | varchar | 乘客id |
driver_id | varchar | 司机id |
status | varchar | 订单状态 |
from | varchar | 起点经纬度(以逗号分割) |
to | varchar | 终点经纬度(以都好分割) |
distance | double | 距离 |
duration | bigint | 花费时间 |
在HotArea表中,随机获取两个不同的地址,作为一条订单记录的起点和终点,并随机一个2022-5-1 到当前的一个时间作为订单开始时间。通过腾讯地图开放api 批量距离计算(矩阵)来计算。调用该接口可以返回行车距离和行车时间。这样即可完成表中关键数据的生成。
package com.example.point.predict;import com.alibaba.fastjson.JSONObject;
import com.example.point.app.MapService;
import com.example.point.domain.entity.PoOrder;
import com.example.point.domain.mapper.HotAreaDao;
import com.example.point.domain.mapper.PoOrderDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.io.IOException;
import java.text.ParseException;
import java.util.Date;
import java.util.Random;@Service
public class GeneralOrderData {@Autowiredprivate HotAreaDao hotAreaDao;@Autowiredprivate PoOrderDao orderMapper;public void generalData() throws IOException, ParseException {// hotArea 表中存在992 条数据,随机0-992 之间的数并以主键id查询int fromIndex = (int) (Math.random() * 993);int toIndex = (int) (Math.random() * 993);// 避免重复while (fromIndex == toIndex) {toIndex = new Random(992).nextInt();}HotArea fromHotArea = hotAreaDao.selectByPrimaryKey(fromIndex);HotArea toHotArea = hotAreaDao.selectByPrimaryKey(toIndex);// 获取行车距离,行车时间;MapService 内部通过OkHttp3完成对Tencent 地图api的访问String json = new MapService().getDistance("driving", fromHotArea.getLatitude().concat(",").concat(fromHotArea.getLongitude()), toHotArea.getLatitude().concat(",").concat(toHotArea.getLongitude()));// 通过fastjson进行解析,接下来的distance和duration即为距离和时间,单位米和秒JSONObject jsonObject = JSONObject.parseObject(json).getJSONObject("result").getJSONArray("rows").getJSONObject(0).getJSONArray("elements").getJSONObject(0);String distance = jsonObject.getString("distance");String duration = jsonObject.getString("duration");// 随机2022-5-1 之后的一个时间戳,作为订单开始时间。并与duration相加计算可得到结束时间long day = 864000;long startTime = (long) (Math.random() * (day + 1)) + 1651334400;long endTime = startTime + Long.parseLong(duration);// 订单信息封装类PoOrder poOrder = PoOrder.builder().beginTime(new Date(startTime * 1000)).endtime(new Date(endTime * 1000)).cost(new MapService().getCost(Double.parseDouble(distance))).orgin(fromHotArea.getTitle()).destination(toHotArea.getTitle()).from(fromHotArea.getLatitude().concat(",").concat(fromHotArea.getLongitude())).to(toHotArea.getLatitude().concat(",").concat(toHotArea.getLongitude())).driverId(String.valueOf(1000 + (int)(Math.random() * 101))).clientId(String.valueOf(2000 + (int)(Math.random() * 101))).status("完成").distance(Double.valueOf(distance)).duration(Long.valueOf(duration)).build();// 持久化订单记录orderMapper.insert(poOrder);}
}
// 订单封装类
package com.example.point.domain.entity;import java.io.Serializable;
import java.util.Date;import lombok.Builder;
import lombok.Data;/*** po_order* @author */
@Data
@Builder
public class PoOrder implements Serializable {private Long orId;/*** 起点*/private String orgin;/*** 终点*/private String destination;/*** 开始时间*/private Date beginTime;/*** 结束时间*/private Date endtime;/*** 备注信息*/private String node;/*** 费用*/private Double cost;/*** 乘客id*/private String clientId;/*** 司机id*/private String driverId;/*** 订单状态*/private String status;/*** 起点经纬度(以逗号分割)*/private String from;/*** 终点经纬度(以都好分割)*/private String to;/*** 行车距离*/private Double distance;/*** 行车时间)*/private Long duration;private static final long serialVersionUID = 1L;
}
// 订单持久化接口,BaseMapper 是Mybatis Plus 提供的mapper接口,其实并不需要理解这个类,实际上就是将一条订单保存到数据库中,可以有很多种方法
package com.example.point.domain.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.point.domain.entity.PoOrder;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface PoOrderDao extends BaseMapper<PoOrder> {int deleteByPrimaryKey(Long orId);int insert(PoOrder record);int insertSelective(PoOrder record);PoOrder selectByPrimaryKey(Long orId);int updateByPrimaryKeySelective(PoOrder record);int updateByPrimaryKey(PoOrder record);
}
// 批量执行 生成订单数据
package com.example.point.predict;import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.io.IOException;
import java.text.ParseException;@SpringBootTest
class GeneralOrderDataTest {@Autowiredprivate GeneralOrderData generalOrderData;@Testvoid generalData() {try {for (int i = 1; i < 999; i++) {System.out.println(i);if (i % 50 == 0) {System.out.println("休眠 " + i);// 休眠是因为地图api访问频度太高会拒绝Thread.sleep(10000);}generalOrderData.generalData();}} catch (IOException e) {e.printStackTrace();} catch (ParseException e) {e.printStackTrace();} catch (InterruptedException e) {e.printStackTrace();}}
}
结果如上图 生成的订单数据 所示
总结
通过该项目基本完成了所需要的订单数据生成,但是思考发现数据距离真实数据还有很大差别。
- 订单起点终点:选择仍然只是理论上的热点,实际上可能存在大量在小区、医院、公司的订单数据。
- 订单开始时间:代码中只做了随机,实际上在早晚高峰也是打车的高峰期,单纯随机并不能反映出这一定。
- 订单真实性:发现某些数据的里程数在40公里及以上,订单价格以每公里1.9 元计算最高达到了900元,实际上这种订单大概率不会发生。
- 优化手段:可以通过出租车gps 数据进行分析,获取到打车热力图并以此作为订单起点。对时间进行加权随机,对公里数做出限制,如果发现公里数大于30则进行筛选,仅生成1/4 的大公里数据。
数据及源码
热点城市数据(HotArea)992条 | hot_area.sql |
订单数据(PoOrder)约1500条 | po_order.sql |
代码 | 稍后总结 |
基于java 生成打车网约车订单测试数据相关推荐
- 基于QT的滴滴网约车订单数据可视化分析
全套资料下载地址:https://download.csdn.net/download/sheziqiong/85584944?spm=1001.2014.3001.5503 [摘要]在万物联网的当下 ...
- 城际网约车订单分配问题及其求解算法
城际网约车订单分配问题及其求解算法 问题的定义 数学建模 用于城际网约出行的智能订单分配算法 智能订单分配算法 基于时间序列和距离信息的启发式方法 基于邻域操作的局部搜索 动态订单分配机制 自适应订单 ...
- 打车/网约车、代驾、顺风车/拼车/快车/专车(含市内和城际)、货运(小程序、APP(安卓/苹果)、公众号、H5网页)
打车出行平台支持打车/网约车.代驾.顺风车/拼车/快车/专车(含市内和城际).货运.租车,可快速上线运营. 打车网约车拼车平台:打车+代驾+顺风车+货运 基础功能模块 NO.1[ 乘客端 ] 01.多 ...
- 打车网约车代驾APP软件主要功能及要解决的痛点
一.打车软件主要功能及要解决的痛点: 1.多种打车模式:快车.专车.顺风车.城际城乡车.分流车.拼车.代驾.出租车.货运.城际巴士等多种业务模式 2.多终端:微信公众号.微信小程序.Android软件 ...
- 数据可视化第二版-拓展-和鲸网约车分析一等奖作品
文章目录 数据可视化第二版-拓展-网约车分析案例 竞赛介绍 1等奖作品-IT从业者张某某的作品 结论 过程数据和思考 数据处理 数据探索 数据分析方法选择 数据分析 相关性分析 转化率分析 分析结论 ...
- 第七期 | 网约车司机的“捞偏门”手段:作弊抢单、空跑刷单
顶象防御云业务安全情报中心监测到,多个网约车出行平台存在作弊软件抢单.空跑刷单等欺诈行为,不仅损害乘客利益,更严重影响平台正常运营. 据顶象防御云业务安全情报BSL-2022-a3c7号显示,部分网约 ...
- T3出行夺冠,如祺出行、曹操出行追赶,网约车行业的“新故事”在哪?
文/智能相对论(aixdlun) 作者/青月 据网约车监管信息交互平台最新数据披露,2020年12月份,我国网约车订单信息共计8.1亿单,相比11月份的增长率,T3出行夺冠,其12月份的订单增速高达1 ...
- “功能”之后,网约车决胜“服务”
文丨智能相对论 作者丨陈先森 网约车在"安全"."合规"的道路上奔跑,却始终没有跳过"服务"这块绊脚石. 不久前上海发布2022年上半年网约 ...
- 网约车行业格局加速重构 T3出行如何打开增长新通道?
7月7日至9日,2022第十四届中国汽车蓝皮书论坛在武汉举行.T3出行CEO崔大勇受邀出席论坛,并发表题为"出行新变局 增长新思维"的主题演讲. 崔大勇现场分享了T3出行上线近三年 ...
最新文章
- React 中的父子组件 兄弟组件传值
- android 标题栏不显示?
- linux重启后版本变了,linux – 重启后如何使设备映射保持不变?
- 在ASP.NET 2.0中实现URL重写
- linux管道操作命令,Linux中可用于管道操作的命令总结
- 【英语语法】学习路线
- C++之个人银行账户管理程序
- 松翰SN8P2511 SOP8单片机 可代烧录 提供单片机方案开发 单片机解密
- u盘安装系统win2019服务器系统,U盘如何安装原版Windows server 2019?
- eNB、gNB、en-gNB和ng-eNB的区别
- 利用libpcap捕获DPDK网络包
- 语音房间实现的一种方式
- 浅谈上溢overflow和下溢underflow
- keras教程【2】编写CNN
- eos 测试网搭建,单节点,并使用命令行完成系统合约部署、账户创建、资产转账
- MySQL春节收支表怎么建立_怎样建立收支账目表
- 这个夏天,迅雷“惹火了”区块链开发者|大赛
- 药店管理系统源码 药店管理信息系统源码带文档
- Python全栈[第二篇]:计算机基础知识-进制
- 前端LayUI框架快速上手详解(一)