阿里工程师如何叫外卖?99%的人猜不到
阿里妹導讀:為了解決訂餐的煩惱,來自高德的阿里工程師勤碩,用技術做了一個非常好玩的事情,希望能給你帶來一些啟發,讓我們一起快樂工作、認真生活。
情景重現
“啪啪啪…”,在一陣急促的鍵盤敲擊聲中,時間不知不覺已經到了4點60分,我已經坐在顯示器前超過3個小時了,辦公室又熱又悶,可以明顯覺察到空氣是不流通的,電腦的風扇散熱提醒我應該調整一下姿勢。
于是我決定起來走一走,站起身,突然覺得身體有點異樣,餓了…
一看表,已經是4點61分。完蛋,又完美地錯過了5點的訂餐時間… 看來今天的晚餐注定又要湊合挨餓了。哎,要是有一個提醒我及時訂飯的服務就好了,鬧鐘?不不,那么low的東西怎么能彰顯我的geek精神呢。
對,做一個釘釘機器人吧,不不,只做一個機器人怎么夠,既然要做就做個全套的,再研究一下美餐的訂餐數據,找到最好吃的最受歡迎的套餐,恩,聽起來不錯,就這樣,動手!
背景介紹
在開始今天的“故事”之前,先跟大家科普一下:美餐App。
這個外賣App的主要功能,是每天能夠定時定點投喂外賣給加班的程序猿,而美餐的訂餐最后截止時間在每天的下午5點準時停止。所以如果你沉迷工作廢寢忘食而錯過了投食的申請時間,那么抱歉,對于沒有時間出去吃一頓的加班汪來說,你就要餓肚子了…
如何抓取數據?
美餐的數據是個很頭疼的問題,因為美餐并不是一個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),這就十分貼心了,這個數據就可以用來分析餐廳受歡迎的情況。
如何設計一個發通知的機器人?
我們已經得到了數據,那么就需要完成計劃的第一步,做一個釘釘機器人來告訴我“該訂餐了”。步驟如圖所示:
打開釘釘的聊天窗口,找到機器人
直接添加機器人,然后選擇自定義機器人
然后下一步,最后會給你一個webhook,那個就是用來發送推送的hook
然后只需要在代碼里合適的時機post這個webhook 就可以觸發機器人在當前聊天群里的動作了
推送有個很好的功能就是支持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個小時的時候通知我,代碼會隔一分鐘訪問一次接口,這樣就不會在同一分鐘內通知我兩遍,這樣推送的代碼就完成了(代碼我會放在文章結束)。
另外我還在推送內容里加上一張來自網絡的隨機美圖來促進我的食欲。
最后把工程放入Docker里,每天在后臺跑著,通過機器人定時推送給我消息,就再也不用擔心錯過訂餐啦~
終極問題——吃什么?
吾日三省吾身,早中晚餐該吃啥。
對于有選擇恐懼癥的我來說,每天在思考吃什么這個終極哲學問題上浪費了大量的時間,而且在App上并沒有圖示和評價,所以這大概是一次基于個人經驗和口口相傳的盲選…
為了解決這個問題,我們抓到的數據不正好派上用場嘛,于是我把所有時間點的所有店鋪的數據都抓下來看看。
看看數據
然而真實情況是數據量并不大,我嘗試過抓取幾個月前半年以前的數據,但是發現所有的數據大概只會保存一個月左右的。
可以看到店鋪大致都是分布在公司的周圍,畢竟太遠的也不會承接這么大規模的送餐。有一個比較好玩的是有一個很奇葩的店鋪開在海上,恩… 這一定是個臟數據…
得到數據之后,我們先來計算每日總訂餐率,取了60天的數據,去除了一些干擾數據之后,用當天所有實際餐廳訂餐數除以餐廳可訂總數,得到每日總訂餐數(r為出現餐廳數量,order為該餐廳訂餐數,dish為該餐廳可訂總量):
這樣可以反映出當天的總體訂餐情況,可以看到起數據還是有明顯起伏的。然后我檢查了他們對應的時間,其中10-29日達到了100%訂餐,也就是所有店鋪的餐全部訂光了,檢查了一下數據,發現那一天只有一家店鋪在提供晚飯,所以被訂光也是可以理解的。
之后計算餐廳的平均訂餐率(雖然餐廳數據量級比較小,但訂餐率也能在某種程度上反映餐廳的訂餐實際情況,也不失為一種判斷標準),具體來說就是將餐廳出現天數中的訂餐量之和除以可訂餐總量之和,餐廳訂餐率如下:(days為出現天數,order為訂餐數,dish為可訂總量):
這也就側面反映了餐廳的受歡迎程度。計算后發現近60天的訂餐率最高的是金百萬,有87.7%的訂餐率,成為最受大家歡迎的店鋪,其次是麗華快餐,訂餐率達到87.1%,第三名是小芝麻。而最不受歡迎的店鋪果然是蘭州牛肉拉面,訂餐率只有12.3%,這也挺符合大家平時的評價…
通過這樣就找到公司附近這段時間最優質的外賣,對于我這種選擇恐懼癥來說,大大縮短了選擇的時間,還可以定期看一看最近的店鋪情況,會第一時間發現有新的店鋪加入,這樣就在訂餐的時候,掌握更多更好的信息。比較遺憾的是,美餐并不提供每個餐廳里菜品的訂餐數據,不然我們就可以根據這個選擇最受歡迎的菜品。
寫在最后
因為實際需求的關系,所以只做了美餐的數據爬取和分析,希望本文能夠拋磚引玉,有興趣的同學也可以對其它外賣平臺做一些數據的挖掘分析,拯救每天思考吃什么的終極哲學問題。
如果大家有什么更好的解決方案,也歡迎在留言區討論,我們一起探討交流~
總結
以上是生活随笔為你收集整理的阿里工程师如何叫外卖?99%的人猜不到的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 阿里搜索技术,在AI路上走了多远?
- 下一篇: 如何让进口商品拥有正品“身份证”?解析区