// ==UserScript== // @name 美团商家流量导出Excel // @namespace http://tampermonkey.net/ // @version 0.1.4 // @description 增加了流量来源 // @author yhpl-pgq // @match https://shangoue.meituan.com/* // @require http://cdn.staticfile.org/xlsx/0.16.1/xlsx.mini.min.js // @grant GM_xmlhttpRequest // @downloadURL none // ==/UserScript== (function() { 'use strict'; addButton(); console.log('enter') })(); var xmlExportContent = {traffic:[], source:[]}; var yhplHTTPCount = 0; function addButton(){ var headerLeft = $("#reload-page")[0]; var header = headerLeft.parentElement; var button = document.createElement('BUTTON'); button.innerText = "我是小可爱"; button.onclick = getStore; button.id = "yhplExport"; header.appendChild(button); } function onStoreSuccess(node){ var code = node.code window.node = node; console.log('onSuccess, code:'+code); if (code == 0){ var data = node.data; var length = data.length; var totalRequestSize = length * 2; // length = 2; //totalRequestSize = length * 2; for(var poi = 0; poi < length; poi++){ var child = data[poi]; console.log(child.poiName+"," +child.id); // if (poi < 3){ getStoreDetail(poi * 2, totalRequestSize, child.id, child.poiName); getStoreTrafficSource(poi * 2 + 1, totalRequestSize, child.id, child.poiName); //} } } } function onStoreError(e){ console.log(e); console.log('onError'); } function getStore(){ yhplHTTPCount = 0; xmlExportContent = {traffic:[], source:[]}; xmlExportContent.traffic.push(['店铺名字', '指标名称', '当前', '7日对比', '行业对比']) xmlExportContent.source.push(['店铺名字', '指标名称','曝光人数', '搜索', '商家列表', '订单页', '其他', '活动专区', '为你优选']) console.log('req user'); var URL_STORE = 'https://shangoue.meituan.com/api/poi/poiList'; $.ajax({ type: "POST", url: URL_STORE, data: '', success: onStoreSuccess, error:onStoreError, dataType: 'json' }); } function onStoreDetailSuccess(step, total, text, storeID, storeName){ //console.log('onStoreDetailSuccess:'+text); var node = JSON.parse(text); var code = node.code console.log('onSuccess, code:'+code); if (code == 0){ var data = node.data; var storeDetailRows = []; if (data != null) { var length = data.length; for(var index = 0; index < length; index++){ var child = data[index]; var indexStr = child.index; var indexParsed = acceptDataNode(indexStr); var indexInt = getTrafficIndexAsInt(indexStr); if (indexParsed.length > 0 && indexInt >= 0){ var current = child.current; var ring = child.ring; var peer= child.peer; if (peer== null && ring == null && peer == null) { continue; } var storeDetailRow = []; storeDetailRow.push(getStoreName(storeName, storeID)); storeDetailRow.push(indexParsed); storeDetailRow.push(appendDateSuffix(indexStr, current)); storeDetailRow.push(appendDateSuffix(indexStr, ring)); storeDetailRow.push(appendDateSuffix(indexStr, peer)); storeDetailRows[indexInt] = storeDetailRow; // console.log(child.index+"," +child.current); } } var rows = storeDetailRows.length; for(var rowIndex = 0; rowIndex < rows; rowIndex++){ var row = storeDetailRows[rowIndex]; if(row == null){ continue; } xmlExportContent.traffic.push(row); } } else { console.log('数据获取失败:'+storeID); } showProgress(step, total); } } function getStoreName(storeName, storeID){ if (storeID > 0){ return (storeName+"("+storeID+")"); } else { return storeName; } } function onStoreTrafficSourceSuccess(step, total, text, storeID, storeName){ var node = JSON.parse(text); var code = node.code //console.log('onSuccess, code:'+code); if (code != 0) { console.log('流量来源数据获取失败#1:'+storeID); showProgress(step, total); return; } var data = node.data; if(data == null) { console.log('流量来源数据获取失败#2:'+storeID); showProgress(step, total); return; } var detail = data.detail; if (detail == null) { console.log('流量来源数据获取失败#3:'+storeID); showProgress(step, total); return; } var storeTrafficSourceRows = ['未知', '曝光来源', 0, 0, 0, 0, 0, 0, 0]; storeTrafficSourceRows[0] = getStoreName(storeName, storeID); storeTrafficSourceRows[2] = data.current; var length = detail.length; for(var index = 0; index < length; index++){ var child = detail[index]; var indexStr = child.index; var indexParsed = getIndexAsInt(indexStr); if (indexParsed>=0){ storeTrafficSourceRows[indexParsed + 3] = child.current; } } xmlExportContent.source.push(storeTrafficSourceRows); showProgress(step, total); } function appendDateSuffix(index, val){ if (val == null){ return ""; } if (index.indexOf('RATE')>=0){ val = val + "%"; } return val; } function acceptDataNode(index) { switch (index){ case "FLOW_POI_EXPOSE_UV": return "曝光人数"; case "FLOW_POI_EXPOSE_PV": return "曝光次数"; case "FLOW_WEIGHTED_AVG_RANKING": return "平均排名"; case "FLOW_HOME_PAGE_EXPOSE_RATE": return "入店转化率"; case "FLOW_HOME_PAGE_UV": return "入店人数"; case "FLOW_HOME_PAGE_PV": return "入店次数"; case "FLOW_HOME_PAGE_DURATION": return "入店访问时长"; case "FLOW_SUBMITTED_HOME_PAGE_RATE": return "下单转化率"; case "FLOW_SUBMITTED_UV": return "下单人数"; case "FLOW_SUBMITTED_PV": return "下单次数"; case "FLOW_SUBMITTED_ACTUAL_AMT": return "下单金额"; case "FLOW_PAY_UV": return "支付人数"; case "FLOW_PAY_ACTUAL_AMT": return "支付金额"; case "FLOW_PAY_SUBMITTED_RATE": return "支付转化率"; default: return index; } } function getTrafficIndexAsInt(index) { switch (index){ case "FLOW_POI_EXPOSE_UV": return 0; case "FLOW_POI_EXPOSE_PV": return 1; case "FLOW_WEIGHTED_AVG_RANKING": return 2; case "FLOW_HOME_PAGE_EXPOSE_RATE": return 3; case "FLOW_HOME_PAGE_UV": return 4; case "FLOW_HOME_PAGE_PV": return 5; case "FLOW_HOME_PAGE_DURATION": return 6; case "FLOW_SUBMITTED_HOME_PAGE_RATE": return 7; case "FLOW_SUBMITTED_UV": return 8; case "FLOW_SUBMITTED_PV": return 9; case "FLOW_SUBMITTED_ACTUAL_AMT": return 10; case "FLOW_PAY_UV": return 11; case "FLOW_PAY_ACTUAL_AMT": return 12; case "FLOW_PAY_SUBMITTED_RATE": return 13; default: return -1; } } function getIndexAsInt(index){ switch (index){ case "FLOW_SOURCE_FROM_SEARCH": return 0; case "FLOW_SOURCE_FROM_POI_LIST": return 1; case "FLOW_SOURCE_FROM_ORDER_PAGE": return 2; case "FLOW_SOURCE_FROM_OTHER": return 3; case "FLOW_SOURCE_FROM_ACT_AREA": return 4; case "FLOW_SOURCE_FROM_SELECTED": return 5; default: return -1; } } function getStoreDetail(index, total, storeID, storeName){ var URL_PREFIX = 'https://waimaieapp.meituan.com/igate/recoanalysis/flowAnalysisV4/recentDays/flowTransformation?acctId=69808847&source=0&recentDays=7'; var storeParmas = '&cityIds=0&wmPoiId='+storeID; var URL_DETAIL = URL_PREFIX + storeParmas GM_xmlhttpRequest({ method: "GET", url: URL_DETAIL, data: '', headers: { "Referer": "https://waimaieapp.meituan.com/igate/", "Content-Type": "application/x-www-form-urlencoded" }, onload: function(res){ if(res.status === 200){ // console.log('成功') //console.log(res); onStoreDetailSuccess(index, total, res.response, storeID, storeName); }else{ //console.log('失败') console.log(res) } }, onerror : function(err){ console.log('error') console.log(err) } }); } function getStoreTrafficSource(index, total, storeID, storeName){ var URL_PREFIX = 'https://waimaieapp.meituan.com/igate/recoanalysis/flowAnalysisV4/recentDays/flowTrafficSource?acctId=69808847&source=0&recentDays=7'; var storeParmas = '&cityIds=0&wmPoiId='+storeID; var URL_DETAIL = URL_PREFIX + storeParmas GM_xmlhttpRequest({ method: "GET", url: URL_DETAIL, data: '', headers: { "Referer": "https://waimaieapp.meituan.com/igate/", "Content-Type": "application/x-www-form-urlencoded" }, onload: function(res){ if(res.status === 200){ onStoreTrafficSourceSuccess(index, total, res.response, storeID, storeName); }else{ console.log(res) } }, onerror : function(err){ console.log('error') console.log(err) } }); } function showProgress(step, total){ yhplHTTPCount = yhplHTTPCount + 1; console.log('step:'+yhplHTTPCount); var button = $("#yhplExport")[0]; button.innerText = "导出进度:"+yhplHTTPCount + "/ "+total; console.log(xmlExportContent); if (yhplHTTPCount >= total){ button.innerText = "下载Excel"; exportAsXLS(xmlExportContent); } } //segment excel function exportAsXLS(table){ var excelName = "流量分析.xlsx"; var sheet = XLSX.utils.aoa_to_sheet(table.traffic); var source = XLSX.utils.aoa_to_sheet(table.source); openDownloadDialog(sheet2blob([{sheet: sheet,name:'流量分析'},{sheet: source,name:'流量来源'}]),excelName); } function sheet2blob(sheets) { var sheetsSize = sheets.length; var SheetNames = []; var Sheets = {}; for (var index = 0; index