diff --git a/platformapi/mtwmapi/mtwmapi.go b/platformapi/mtwmapi/mtwmapi.go index e8f5704f..fcb252ff 100644 --- a/platformapi/mtwmapi/mtwmapi.go +++ b/platformapi/mtwmapi/mtwmapi.go @@ -9,6 +9,7 @@ import ( "net/url" "sort" "strings" + "sync" "time" "git.rosy.net.cn/baseapi" @@ -51,6 +52,9 @@ type API struct { callbackURL string client *http.Client config *platformapi.APIConfig + + locker sync.RWMutex + userCookies map[string]string } var ( @@ -71,6 +75,8 @@ func New(appID, secret, callbackURL string, config ...*platformapi.APIConfig) *A callbackURL: callbackURL, client: &http.Client{Timeout: curConfig.ClientTimeout}, config: &curConfig, + + userCookies: make(map[string]string), } } diff --git a/platformapi/mtwmapi/mtwmapi_test.go b/platformapi/mtwmapi/mtwmapi_test.go index 19256bc7..b7383462 100644 --- a/platformapi/mtwmapi/mtwmapi_test.go +++ b/platformapi/mtwmapi/mtwmapi_test.go @@ -1,6 +1,8 @@ package mtwmapi import ( + "net/url" + "strings" "testing" "git.rosy.net.cn/baseapi" @@ -19,6 +21,51 @@ func init() { baseapi.Init(sugarLogger) api = New("589", "a81eb3df418d83d6a1a4b7c572156d2f", "") + + // api.SetUserCookie("_lx_utm", "utm_source%3D60066") + // api.SetUserCookie("_lxsdk", "82B825F99C7098EE5254EB228DC2A863CE34008DFF4AD0913E8DC80D009AA95E") + // api.SetUserCookie("_lxsdk_cuid", "16b8c52943fc8-0f5c424b19a108-2d604637-3d10d-16b8c52943f24") + // api.SetUserCookie("_lxsdk_s", "16b8c529302-353-107-d17%7C%7C11") + // api.SetUserCookie("au_trace_key_net", "default") + // api.SetUserCookie("cssVersion", "b05eaa31") + // api.SetUserCookie("iuuid", "82B825F99C7098EE5254EB228DC2A863CE34008DFF4AD0913E8DC80D009AA95E") + // api.SetUserCookie("mt_c_token", "2Q-NiXyFZ6UViMatiHdP86YpX2QAAAAAqAgAABf6QG4n-W8Zy_l_WLbUUKNmy238OkBp9Fx7rVcqZH6aod8hhhyB3JjfYkOv-7024A") + // api.SetUserCookie("oops", "2Q-NiXyFZ6UViMatiHdP86YpX2QAAAAAqAgAABf6QG4n-W8Zy_l_WLbUUKNmy238OkBp9Fx7rVcqZH6aod8hhhyB3JjfYkOv-7024A") + // api.SetUserCookie("openh5_uuid", "82B825F99C7098EE5254EB228DC2A863CE34008DFF4AD0913E8DC80D009AA95E") + // api.SetUserCookie("showTopHeader", "show") + // api.SetUserCookie("token", "2Q-NiXyFZ6UViMatiHdP86YpX2QAAAAAqAgAABf6QG4n-W8Zy_l_WLbUUKNmy238OkBp9Fx7rVcqZH6aod8hhhyB3JjfYkOv-7024A") + // api.SetUserCookie("w_token", "2Q-NiXyFZ6UViMatiHdP86YpX2QAAAAAqAgAABf6QG4n-W8Zy_l_WLbUUKNmy238OkBp9Fx7rVcqZH6aod8hhhyB3JjfYkOv-7024A") + // api.SetUserCookie("userFace", "") + // api.SetUserCookie("userId", "69979334") + // api.SetUserCookie("userName", "thepool") + // api.SetUserCookie("uuid", "82B825F99C7098EE5254EB228DC2A863CE34008DFF4AD0913E8DC80D009AA95E") + // api.SetUserCookie("wm_order_channel", "default") + // api.SetUserCookie("w_utmz", "utm_campaign=(direct)&utm_source=5000&utm_medium=(none)&utm_content=(none)&utm_term=(none)") + // api.SetUserCookie("w_visitid", "c2d0e4c9-3ab8-4163-b94f-a3dbfd9d7a94") + // api.SetUserCookie("w_actual_lng", "104076656") + // api.SetUserCookie("w_actual_lat", "30665696") + // api.SetUserCookie("w_latlng", "30702250,104052315") + + cookieStr := ` + _lx_utm=utm_source%3D60066; _lxsdk=6A074A0B834664A32E0735231E4FD9C4263666B70A7FEC663F9945110C52EFB3; _lxsdk_cuid=16b8ca9baf5c8-03bbc09a88c9e4-2d604637-3d10d-16b8ca9baf5c8; _lxsdk_s=16b8ca9b8f4-58-f63-4b4%7C18087777%7C19; au_trace_key_net=default; cssVersion=b05eaa31; iuuid=6A074A0B834664A32E0735231E4FD9C4263666B70A7FEC663F9945110C52EFB3; mt_c_token=jeZimbpuoKnPsfoHbT3_CR_w_W0AAAAApQgAAGU0Z9sTXiFzlp-8N8q-UWFdq5xSvYzWOjNhbNK0RGq9m6YaRNc7FtHjpkqFkJ_x2w; oops=jeZimbpuoKnPsfoHbT3_CR_w_W0AAAAApQgAAGU0Z9sTXiFzlp-8N8q-UWFdq5xSvYzWOjNhbNK0RGq9m6YaRNc7FtHjpkqFkJ_x2w; openh5_uuid=6A074A0B834664A32E0735231E4FD9C4263666B70A7FEC663F9945110C52EFB3; token=jeZimbpuoKnPsfoHbT3_CR_w_W0AAAAApQgAAGU0Z9sTXiFzlp-8N8q-UWFdq5xSvYzWOjNhbNK0RGq9m6YaRNc7FtHjpkqFkJ_x2w; userId=69979334; userName=thepool; uuid=6A074A0B834664A32E0735231E4FD9C4263666B70A7FEC663F9945110C52EFB3; wm_order_channel=default; terminal=i; w_utmz="utm_campaign=(direct)&utm_source=5000&utm_medium=(none)&utm_content=(none)&utm_term=(none)"; w_latlng=30694640,104057119; w_visitid=956b412d-c47c-4fec-ae99-7b7cb0c9ab45; w_token=jeZimbpuoKnPsfoHbT3_CR_w_W0AAAAApQgAAGU0Z9sTXiFzlp-8N8q-UWFdq5xSvYzWOjNhbNK0RGq9m6YaRNc7FtHjpkqFkJ_x2w + ` + cookieList := strings.Split(cookieStr, ";") + for _, v := range cookieList { + index := strings.Index(v, "=") + pair := []string{ + v[:index], + v[index+1:], + } + pair[1], _ = url.QueryUnescape(pair[1]) + if strings.Index(pair[1], "\"") >= 0 { + pair[1] = url.QueryEscape(strings.Trim(utils.TrimBlankChar(pair[1]), "\"")) + } + // pair := strings.Split(v, "=") + if len(pair) > 1 { + baseapi.SugarLogger.Debug(pair[0], "=", pair[1]) + api.SetUserCookie(utils.TrimBlankChar(pair[0]), utils.TrimBlankChar(pair[1])) + } + } } func TestAccessAPI(t *testing.T) { diff --git a/platformapi/mtwmapi/user_page.go b/platformapi/mtwmapi/user_page.go new file mode 100644 index 00000000..43c687fe --- /dev/null +++ b/platformapi/mtwmapi/user_page.go @@ -0,0 +1,132 @@ +package mtwmapi + +import ( + "fmt" + "net/http" + "strings" + + "git.rosy.net.cn/baseapi" + "git.rosy.net.cn/baseapi/platformapi" + "git.rosy.net.cn/baseapi/utils" +) + +const ( + userURL = "http://i.waimai.meituan.com" +) + +const ( + ResponseCodeSuccess = 0 +) + +type ListShopItem struct { + Address string `json:"address"` + AveragePriceTip string `json:"averagePriceTip"` + DeliveryTimeTip string `json:"deliveryTimeTip"` + DeliveryType int `json:"deliveryType"` + Distance string `json:"distance"` + MinPriceTip string `json:"minPriceTip"` + MonthSalesTip string `json:"monthSalesTip"` + MtWmPoiID string `json:"mtWmPoiId"` + PicURL string `json:"picUrl"` + PoiTypeIcon string `json:"poiTypeIcon"` + ShippingFeeTip string `json:"shippingFeeTip"` + ShippingTime string `json:"shipping_time"` + ShopName string `json:"shopName"` + Status int `json:"status"` + StatusDesc string `json:"statusDesc"` + WmPoiScore int `json:"wmPoiScore"` +} + +func (a *API) SetUserCookie(key, value string) { + a.locker.Lock() + defer a.locker.Unlock() + a.userCookies[key] = value +} + +func (a *API) GetUserCookie(key string) string { + a.locker.RLock() + defer a.locker.RUnlock() + return a.userCookies[key] +} + +func (a *API) AccessUserPage(subURL string, params map[string]interface{}) (retVal map[string]interface{}, err error) { + a.locker.RLock() + storeCookieLen := len(a.userCookies) + a.locker.RUnlock() + if storeCookieLen == 0 { + return nil, fmt.Errorf("需要设置User Cookie才能使用此方法") + } + err = platformapi.AccessPlatformAPIWithRetry(a.client, + func() *http.Request { + var request *http.Request + fullURL := utils.GenerateGetURL(userURL, subURL, nil) + request, _ = http.NewRequest(http.MethodPost, fullURL, strings.NewReader(utils.Map2URLValues(params).Encode())) + request.Header.Set("charset", "UTF-8") + request.Header.Set("Content-Type", "application/x-www-form-urlencoded") + request.Header.Set("User-Agent", "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1") + request.Header.Set("Pragma", "no-cache") + + a.locker.RLock() + for k, v := range a.userCookies { + request.AddCookie(&http.Cookie{ + Name: k, + Value: v, + }) + } + a.locker.RUnlock() + return request + }, + a.config, + func(response *http.Response, jsonResult1 map[string]interface{}) (errLevel string, err error) { + retVal = jsonResult1 + code := int(utils.MustInterface2Int64(jsonResult1["code"])) + if code == ResponseCodeSuccess { + retVal, _ = jsonResult1["data"].(map[string]interface{}) + return platformapi.ErrLevelSuccess, nil + } + newErr := utils.NewErrorIntCode(jsonResult1["msg"].(string), code) + baseapi.SugarLogger.Debugf("ebai AccessStorePage failed, jsonResult1:%s", utils.Format4Output(jsonResult1, true)) + return platformapi.ErrLevelCodeIsNotOK, newErr + }) + return retVal, err +} + +func (a *API) GetStoreList(lng, lat float64) (shopList []*ListShopItem, err error) { + params := map[string]interface{}{ + "sortId": 1, + "navigateType": 101578, + "firstCategoryId": 101578, + "secondCategoryId": 101578, + "initialLng": lng, + "initialLat": lat, + "geoType": 2, + "wm_longitude": int(lng * 1000000), + "wm_latitude": int(lat * 1000000), + } + startIndex := 0 + for { + params["startIndex"] = startIndex + result, err := a.AccessUserPage("openh5/channel/kingkongshoplist", params) + if err != nil { + return shopList, err + } + var batchShopList []*ListShopItem + if err = utils.Map2StructByJson(result["shopList"], &batchShopList, false); err != nil { + return shopList, err + } + shopList = append(shopList, batchShopList...) + if poiHasNextPage, ok := result["poiHasNextPage"].(bool); !ok || !poiHasNextPage { + break + } + startIndex++ + } + return shopList, nil +} + +func (a *API) GetStoreInfo(storeID string) (storeInfo map[string]interface{}, err error) { + params := map[string]interface{}{ + "mtWmPoiId": storeID, + } + retVal, err := a.AccessUserPage("openh5/poi/info", params) + return retVal, err +} diff --git a/platformapi/mtwmapi/user_page_test.go b/platformapi/mtwmapi/user_page_test.go new file mode 100644 index 00000000..bcf6cd57 --- /dev/null +++ b/platformapi/mtwmapi/user_page_test.go @@ -0,0 +1,43 @@ +package mtwmapi + +import ( + "testing" + + "git.rosy.net.cn/baseapi/utils" +) + +func TestAccessUserPage(t *testing.T) { + result, err := api.AccessUserPage("openh5/channel/kingkongshoplist", map[string]interface{}{ + "startIndex": 0, + "sortId": 1, + "navigateType": 101578, + "firstCategoryId": 101578, + "secondCategoryId": 101578, + "initialLng": 104.076656, + "initialLat": 30.665696, + "geoType": 2, + "wm_longitude": 104076656, + "wm_latitude": 30665696, + }) + if err != nil { + t.Fatal(err) + } + t.Log(utils.Format4Output(result, false)) +} + +func TestGetStoreList(t *testing.T) { + result, err := api.GetStoreList(104.076656, 30.665696) + if err != nil { + t.Fatal(err) + } + t.Log(utils.Format4Output(result, false)) + t.Log(len(result)) +} + +func TestGetStoreInfo(t *testing.T) { + result, err := api.GetStoreInfo("935062809368623") + if err != nil { + t.Fatal(err) + } + t.Log(utils.Format4Output(result, false)) +}