摘要:標簽餐飲外賣,美團,餓了么,百度,爬蟲,數據挖掘爬蟲定時抓取外賣平臺訂單的解決方案想必很多人都在美團,餓了么,百度上點過外賣吧,每家平臺都不定期的發力進行各種瘋狂打折活動,好多人都是三個都安裝的一起比價的策略。
標簽:餐飲外賣,美團,餓了么,百度,爬蟲,數據挖掘
爬蟲定時抓取外賣平臺訂單的解決方案想了解客戶就要收集銷售數據想必很多人都在美團,餓了么,百度上點過外賣吧,每家平臺都不定期的發力進行各種瘋狂打折活動,好多人都是 三個app都安裝的一起比價的策略。而作為大的餐飲企業為了擴大自己的訂單量,也是三家都會上自己的商戶,但是這 三家平臺因為競爭的原因都不支持訂單批量導出功能。這個爬蟲程序就是這個原因而開發出來的。
重復勞動就應該讓機器去做定位客戶,了解客戶有很多種渠道,其中收集訂單信息是比較客觀的數據,我們能從中知道客戶的年齡分布,地理位 置分布,喜歡的口味,消費的層次,購買套餐后還喜歡哪些單點等等問題都能逐漸積累的訂單數據中挖掘出來, 剛開 始這項艱巨的工作是由運營的童鞋們開始的, 她們每天兢兢業業的Ctrl+C , Ctrl+V的拷貝下來百度,美團,餓了么 后臺數據,然后Excel大神生成各種報表,供我們做分析。 但平淡的日子總是漸漸枯燥起來,隨著訂單越來越來,公 司配送點也越來越多, (三個外賣平臺 +自有微信商城) X 配送點 X 每個配送點的訂單的數據就是運營童鞋們的 噩夢。
當運維童鞋正在苦逼復制各種訂單數據時, 我已經想到用爬蟲技術爬取外賣平臺上的訂單了, 這件事并不能,之前 學習Nodejs時候,還寫過一個爬蟲在@煎蛋爬取無聊圖和美女圖呢:>于是開始調研這三家外 賣平臺的后臺系統。
三家后臺采用的頁面技術
平臺 | 后臺展現 | 頁面使用的數據接口 | 可能的抓取方案 |
---|---|---|---|
美團外賣 | 網頁 and 桌面程序 | restful api | 請求獲取json 或者抓取網頁 |
百度外賣 | 桌面程序內嵌webkit | 動態頁面 | 抓取網頁 |
餓了么 | 桌面程序內嵌webkit | restful api | 請求獲取json 或者抓取網頁 |
其中百度外賣后臺頁面非常{{BANNED}},采用動態頁面生成頁面還能接受, 訂單部分數據特意生成 一大段js代碼,
由頁面執行渲染后才顯示出來,這也是后來在抓取時一個坑。
如何抓取數據人工操作流程 抽象出軟件執行流程爬蟲技術簡單說就是用程序模擬人在上網,瀏覽需要的網頁,然后把網頁上需要的內容下載提取出來, 轉換成結構 化的數據保存起來。這些外賣后臺也是一樣,基本上都如下面的流程。
三家外賣平臺抓取的細節都不一樣,但總體上可以用下面的方式表示
更細化一下的表示
核心代碼為/* 爬蟲任務的父類 * 定義抓取流程,各步驟的內容 * 抽取出統一的json to csv生成代碼 */ class FetchTask { /* account:{username:String,password:String} option:{beginTime:moment,endTime:moment} */ constructor(account,option) { this.account = account; let end = moment().subtract(1,"days").endOf("day"); let begin = moment().subtract(option.beforeDays, "days").startOf("day"); logger.info(`Start fetch ${account.name} from ${begin.format("YYYY-MM-DD")} to ${end.format("YYYY-MM-DD")} orders`); this.option = { beginTime: begin, endTime: end }; this.columns = {}; } // 任務執行主方法 run() { return this.preFetch().then(this.fetch.bind(this)).then(this.postFetch.bind(this)); } // 抓取前的準備工作 preFetch() { logger.info(`preFetch ${this.account.name}`); return this.login(); } // 保存登錄憑證 setToken(token){ this.token = token; logger.info(`${this.account.name} gets token :${JSON.stringify(token)}`); } // 執行抓取 fetch() { logger.info(`fetch ${this.account.name}`); return this.fetchPageAmount().then(this.fetchPages.bind(this)); } // 登錄步驟需要子類實現 login() { return; } // 抓取分頁總數 fetchPageAmount(){ return 0; } // 抓取所有分頁上的數據 fetchPages(pageAmount) { let tasks = []; for (let pageNum = 1; pageNum <= pageAmount; pageNum++) { tasks.push(this.fetchPage(pageNum)); } return promise.all(tasks).then((result)=> { return _.flatten(result); }); } // 抓取之后的操作,主要是對原始數據轉換,格式轉換,數據輸出 postFetch(orders){ logger.info(`postFetch ${this.account.name}`); return this.convertToReport(orders).then(this.convertToCSV.bind(this)); } // 原始數據格式轉換 convertToReport(orders){ return orders; } // 在postFetch中將數據轉換成csv格式并生成文件 convertToCSV(orders) { logger.info(`convertToCSV ${this.account.name}`); let option = { header: true, columns: this.columns, quotedString: true }; var begin = this.option.beginTime.format("YYYY-MM-DD"); var end = this.option.endTime.format("YYYY-MM-DD"); let reportFile = this.account.name + begin + "_" + end + "_" + uuid.v4().substr(-4, 4) + ".csv"; let reportPath = path.resolve(__dirname, "../temp", reportFile); return new promise(function (resolve, reject) { stringify(orders, option, function (err, output) { if (err) { reject(err); } fs.appendFile(reportPath, output, { encoding: "utf8", flag: "w+" }, function (err) { if (err) return reject(err); logger.info("Generate a report names " + reportPath); resolve(reportPath); }); }); }); } } module.exports = FetchTask;
每天凌晨6點鐘自動執行抓取任務,定時執行是由later定時庫實現的
const ElemeTask = require("./lib/eleme_task"); const BaiduTask = require("./lib/baidu_task"); const MeituanTask = require("./lib/meituan_task"); const mail = require("./lib/mail"); const logger = require("./lib/logger"); const promise = require("bluebird"); const moment = require("moment"); const config = require("config"); const accounts = config.get("account"); const later = require("later"); function startFetch() { let option = {beforeDays: 1}; let tasks = []; accounts.forEach((account)=> { switch (account.type) { case "meituan": tasks.push(new MeituanTask(account, option).run()); break; case "eleme": tasks.push(new ElemeTask(account,option).run()); break; case "baidu": tasks.push(new BaiduTask(account,option).run()); break; } }); promise.all(tasks).then((files)=> { logger.info("Will send files :" + files); mail.sendMail(option, files); }).catch((err)=> { logger.error(err); }); } later.date.localTime(); let schedule = later.parse.recur().on(6).hour(); later.setInterval(startFetch,schedule); logger.info("Waimai Crawler is running");
按這個結構就是可以實現各個平臺上的抓取任務了,因為不想把文章寫成代碼review,細節可以直接
訪問waimai-crawler
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/79815.html
摘要:可以說,美團要建設的就是配送系統的超級大腦。美團超腦配送系統目前互聯網技術,很大部分還是針對線上產品和系統研發,整個流程可以在線上全部完成,而這也正是配送技術最大的不同和挑戰。 在2018 AI開發者大會(AI NEXTCon)上,美團配送AI方向負責人何仁清,分享了美團在即時配送領域中機器學習技術的最新進展,以及如何通過大數據和機器學習手段,建立對線下真實世界各種場景的感知能力,還原...
閱讀 1652·2021-08-13 15:03
閱讀 2082·2019-08-30 15:54
閱讀 3544·2019-08-26 10:30
閱讀 1020·2019-08-26 10:22
閱讀 2746·2019-08-23 14:42
閱讀 1809·2019-08-22 11:16
閱讀 1038·2019-08-21 18:33
閱讀 3159·2019-08-21 17:28