阿里工程师如何叫外卖?99%的人猜不到

简介: 为了解决订餐的烦恼,来自高德的阿里工程师勤硕,用技术做了一个非常好玩的事情,希望能给你带来一些启发,让我们一起快乐工作、认真生活。

情景重现

“啪啪啪…”,在一阵急促的键盘敲击声中,时间不知不觉已经到了4点60分,我已经坐在显示器前超过3个小时了,办公室又热又闷,可以明显觉察到空气是不流通的,电脑的风扇散热提醒我应该调整一下姿势。

于是我决定起来走一走,站起身,突然觉得身体有点异样,饿了…

一看表,已经是4点61分。完蛋,又完美地错过了5点的订餐时间… 看来今天的晚餐注定又要凑合挨饿了。哎,要是有一个提醒我及时订饭的服务就好了,闹钟?不不,那么low的东西怎么能彰显我的geek精神呢。

对,做一个钉钉机器人吧,不不,只做一个机器人怎么够,既然要做就做个全套的,再研究一下美餐的订餐数据,找到最好吃的最受欢迎的套餐,恩,听起来不错,就这样,动手!

背景介绍

在开始今天的“故事”之前,先跟大家科普一下:美餐App。

这个外卖App的主要功能,是每天能够定时定点投喂外卖给加班的程序猿,而美餐的订餐最后截止时间在每天的下午5点准时停止。所以如果你沉迷工作废寝忘食而错过了投食的申请时间,那么抱歉,对于没有时间出去吃一顿的加班汪来说,你就要饿肚子了…

2648fb1e3f0478542dd0efbce3be7fd81ccd251b

如何抓取数据?

美餐的数据是个很头疼的问题,因为美餐并不是一个2C的应用,它是企业直接对接美餐,员工才有权限去浏览餐厅的信息,所以在网上直接爬数据的传统方法就行不通了。

后来我通过App抓包的方法,发现使用自己的独立账号可以抓到所有高德员工有权限订餐的公开餐厅数据,整理了一下接口之后总结出了从餐厅选择到订餐流程的各个接口的意义(中间还意外的发现了原来美餐还提供了一个web端入口…)。很好,这样就可以直接拿官方公开的数据开始做数据收集工作了。

订餐的第一步,也就是选择可选订餐地点,这个跟员工的部门有关,我也只能看到高德员工可选的地点,得到的数据格式是这样(去掉了一些无关的数据):

// API: https://meican.com/preorder/data/group?x={ userId }
{
groups:[
{ title:"首开", ... },
{ title:"方恒国际", ... },
...
]
}

选择地点之后接着要选择订餐时间点,每个时间点的餐厅会有不同,并且带着当前时间是否可订的状态(这个状态也是我们做订餐机器人判断是否可订餐的重要依据,字段status),接口数据如下(去掉了一些无关数据):

// API: https://meican.com/preorder/api/v2.1/calendarItems/list?beginDate=2017-11-1&endDate=2017-11-8&withOrderDetail=false)
// 默认会得到一周的可订餐信息,也可以设定开始时间和结束时间
{
dateList: [
{
calendarItemList:[
{
openingTime:{
closeTime:"16:30",
...
},
title:"高德地图(首开外卖)晚餐1"
status:"NOT_YET",
...

从接口数据还可以知道订餐截止的时间,那么就可以根据这个做出最晚订餐时间的安排计划,比如我希望能在截止时间前30分钟提醒我。

接着选择我们想要的时间地点组合,例如上面的 “18:30 高德地图(首开外卖)晚餐1”,就会得到所有可选店铺的列表:

// API: https://meican.com/preorder/api/v2.1/restaurants/list?&tabUniqueId=ff4df9a0-9851-4205-adae-b154cc05d811&targetTime=2017-11-01+16:30
{
restaurantList: [
{
availableDishCount:80,
dishLimit:100,
latitude:39.991464,
longitude:116.396763,
name:"宅食送(UBP店)",
...

返回数据里不光有店铺信息和地理位置,居然还有可以总订餐量(dishLimit)和当前可订量(availableDishCount),这就十分贴心了,这个数据就可以用来分析餐厅受欢迎的情况。

如何设计一个发通知的机器人?

我们已经得到了数据,那么就需要完成计划的第一步,做一个钉钉机器人来告诉我“该订餐了”。步骤如图所示:

  1. 打开钉钉的聊天窗口,找到机器人
  2. 直接添加机器人,然后选择自定义机器人
  3. 然后下一步,最后会给你一个webhook,那个就是用来发送推送的hook
  4. 然后只需要在代码里合适的时机post这个webhook 就可以触发机器人在当前聊天群里的动作了
accb597867203f283d0caa7df8046796df4032e8

推送有个很好的功能就是支持markdown,这样就可以很方便的组织内容。

更加详细的推送内容格式和方法参考这里的钉钉官方开发文档:

https://open-doc.dingtalk.com/docs/doc.htm?spm=a219a.7629140.0.0.karFPe&treeId=257&articleId=105735&docType=1

我选用Node.JS来做推送服务,首先是抓取数据,做过滤,格式转换,然后当 ”status“值为“AVAILABLE”且当前时间比结束时间早3个小时的时候通知我,代码会隔一分钟访问一次接口,这样就不会在同一分钟内通知我两遍,这样推送的代码就完成了(代码我会放在文章结束)。

另外我还在推送内容里加上一张来自网络的随机美图来促进我的食欲。

e8aa99d5c5542d583e934c057b26834c5244ef74

最后把工程放入Docker里,每天在后台跑着,通过机器人定时推送给我消息,就再也不用担心错过订餐啦~

终极问题——吃什么?

吾日三省吾身,早中晚餐该吃啥。

对于有选择恐惧症的我来说,每天在思考吃什么这个终极哲学问题上浪费了大量的时间,而且在App上并没有图示和评价,所以这大概是一次基于个人经验和口口相传的盲选…

为了解决这个问题,我们抓到的数据不正好派上用场嘛,于是我把所有时间点的所有店铺的数据都抓下来看看。

看看数据\

然而真实情况是数据量并不大,我尝试过抓取几个月前半年以前的数据,但是发现所有的数据大概只会保存一个月左右的。

0a6435f3c57f8c5b80f17bb1b1e12f69f76b0ecc

全部出现过的店铺数据

c794984d6737df83a70cb82a0b046296a3ea4acb

高德望京周围店铺地理位置图

可以看到店铺大致都是分布在公司的周围,毕竟太远的也不会承接这么大规模的送餐。有一个比较好玩的是有一个很奇葩的店铺开在海上,恩… 这一定是个脏数据…

6f4884d910d9cc0422d1242f27e6b4a525404017

得到数据之后,我们先来计算每日总订餐率,取了60天的数据,去除了一些干扰数据之后,用当天所有实际餐厅订餐数除以餐厅可订总数,得到每日总订餐数(r为出现餐厅数量,order为该餐厅订餐数,dish为该餐厅可订总量):

4955175a6c0a1a5a8c52f8a9ece61b70876e8ba7

这样可以反映出当天的总体订餐情况,可以看到起数据还是有明显起伏的。然后我检查了他们对应的时间,其中10-29日达到了100%订餐,也就是所有店铺的餐全部订光了,检查了一下数据,发现那一天只有一家店铺在提供晚饭,所以被订光也是可以理解的。

e3db5dd18bdc4a1e443770b9f1e19b43e43902d9

之后计算餐厅的平均订餐率(虽然餐厅数据量级比较小,但订餐率也能在某种程度上反映餐厅的订餐实际情况,也不失为一种判断标准),具体来说就是将餐厅出现天数中的订餐量之和除以可订餐总量之和,餐厅订餐率如下:(days为出现天数,order为订餐数,dish为可订总量):

f4469a51fa16f71ae5487e3e40a5a64e427143b4

这也就侧面反映了餐厅的受欢迎程度。计算后发现近60天的订餐率最高的是金百万,有87.7%的订餐率,成为最受大家欢迎的店铺,其次是丽华快餐,订餐率达到87.1%,第三名是小芝麻。而最不受欢迎的店铺果然是兰州牛肉拉面,订餐率只有12.3%,这也挺符合大家平时的评价…

702da1d6873cbdb992fab3e0383c5343e29d3732

通过这样就找到公司附近这段时间最优质的外卖,对于我这种选择恐惧症来说,大大缩短了选择的时间,还可以定期看一看最近的店铺情况,会第一时间发现有新的店铺加入,这样就在订餐的时候,掌握更多更好的信息。比较遗憾的是,美餐并不提供每个餐厅里菜品的订餐数据,不然我们就可以根据这个选择最受欢迎的菜品。

写在最后

因为实际需求的关系,所以只做了美餐的数据爬取和分析,希望本文能够抛砖引玉,有兴趣的同学也可以对其它外卖平台做一些数据的挖掘分析,拯救每天思考吃什么的终极哲学问题。


原文发布时间为:2018-01-03
本文作者:勤硕
本文来自云栖社区合作伙伴“ 阿里技术”,了解相关信息可以关注“ 阿里技术”微信公众号
相关文章
|
7月前
|
测试技术 数据库
腾讯游戏测试工程师的经验心得分享
腾讯游戏测试工程师的经验心得分享
287 0
|
2月前
|
机器人 程序员 C++
Scratch3.0——助力新进程序员理解程序(案例一十五、猜数字)
Scratch3.0——助力新进程序员理解程序(案例一十五、猜数字)
34 0
|
9月前
|
架构师
快乐学习顺利通关——架构师考试通关总结
通过这篇博文我将给大家介绍如何快乐的学习,如何顺利的通关,如何在过程中体会感受学习的方式方法。
|
开发者
【开发者7日学】求职达人训练营上线啦~快来打卡赢好礼
阿里云培训中心联合开发者社区推出求职达人训练营7天学习活动,由阿里师兄们围绕行业介绍、职业选择、职场经验等内容进行分享,帮助大学生快速了解真实职场环境、提升实用求职技巧、培养必备职业素养等。
【开发者7日学】求职达人训练营上线啦~快来打卡赢好礼
|
消息中间件 Cloud Native Serverless
恭喜我的同事丁宇入选年度 IT 领军人物
阿里巴巴研究员、阿里云智能云原生应用平台负责人丁宇(花名:叔同)在CSDN 和《新程序员》特别举办“开发者生态汇 —— 2022 IT 技术影响力之星”活动中获得年度 IT 领军人物
恭喜我的同事丁宇入选年度 IT 领军人物
|
新零售 边缘计算 分布式计算
20位阿里出题专家-备战阿里必不可少的题目
出题人:阿里巴巴新零售技术质量部
2266 0
|
机器学习/深度学习 人工智能 自然语言处理
15篇面试通关经验+10大热招岗位,给你足够底气斩获offer!|开发者必读(164期)
人生有许多种可能,只要勇敢一次,你会发现收获的东西比想象中多很多,譬如说,我们正在招人,你勇敢投简历了吗?如果你还没有准备好,没关系,我们给你足够底气斩获offer!10大热招岗位需求+15篇师兄师姐面试经验分享,手把手教你面试通关!
|
程序员 Java 开发工具
阿里工程师谈,什么是好的代码?
我们每天都与代码打交道,但当被问道什么是好的代码时,很多人可能会先愣一下,然后给出的回答要么比较空泛,要么比较散,没办法简单明了地概括出来。显然,这个问题并没有唯一的标准答案,谁都可以谈论自己的理解,今天谈谈我对于好代码的理解。
7640 0
阿里工程师谈,什么是好的代码?
|
算法 存储 人工智能
凑单这个技术活,阿里工程师怎么搞?
凑单作为购物环节重要的环节,具有帮助用户提高优惠购物效率与购物探索性两大重要角色。
1123 0
不断进阶:从“学渣”到P10,一位阿里工程师的逆袭故事
红雪高中毕业,没上大学四处打零工,路边修过自行车,也做过理发店小弟,连自考的考试都没通过。但现在他已成为蚂蚁金服的研究员,带领大几百号人的技术团队,最近还入选了“全球35位35岁以下科技创新青年”。
9044 0