using Api.Framework.Cps; using CsharpHttpHelper; using CsharpHttpHelper.Enum; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; namespace Api.Framework.Tools { /// /// 拼多多解析助手 /// public class PDDHelper { ///// ///// 随机对象 ///// //private static Random random = new Random(Guid.NewGuid().GetHashCode()); ///// ///// 获取随机公共拼多多查询商品信息账号 ///// ///// //public static fl_cps_member RandomGuidePddMembers() //{ // try // { // //return CpsClient.GuideMembers[0]; // return CpsClient.GuideMembers[random.Next(0, CpsClient.GuideMembers.Count)]; // } // catch (Exception ex) // { } // return CpsClient.GuideMembers.FirstOrDefault(); //} /// /// 多多进宝app中获取高佣商品的招商id /// /// 商id /// public static string FindGoodsSign_H5(string goodsid) { try { try { if (GoodsCacheDic.ContainsKey(goodsid)) { var GoodsCache = GoodsCacheDic[goodsid]; if (GoodsCache.GetTime.AddHours(1) > DateTime.Now) return GoodsCache.GoodsSign; GoodsCacheDic.Remove(goodsid); } } catch (Exception) { } for (int i = 0; i < 3; i++) { try { HttpHelper http = new HttpHelper(); HttpItem item = new HttpItem() { URL = "https://jinbaoh5.pinduoduo.com/network_h5/weak_auth/goods/query_goodslist", Method = "POST", Timeout = 100000, ReadWriteTimeout = 30000, IsToLower = false, Cookie = "", UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0", Accept = "text/html, application/xhtml+xml, */*", ContentType = "application/json", Referer = "", Allowautoredirect = false, AutoRedirectCookie = false, Postdata = @"{""hasCoupon"": false,""pageNumber"": 1,""sortType"": 0,""listId"": """",""pageSize"":10,""keyword"":""" + goodsid + @"""}", ResultType = ResultType.String }; HttpResult result = http.GetHtml(item); string html = result.Html; var jobj = JObject.Parse(html); if (!(bool)jobj["success"]) continue; else { var goodsList = (JArray)jobj["result"]["goodsList"]; for (int z = 0; z < goodsList.Count; z++) { //var zsDuoId = (int)goodsList[0]["zsDuoId"]; //if (zsDuoId == 0) return string.Empty; //return zsDuoId.ToString(); var goodsSign = goodsList[0]["goodsSign"].ToString(); if (!string.IsNullOrWhiteSpace(goodsSign)) { return goodsSign; } } } } catch (Exception ex) { } finally { Thread.Sleep(200); } } } catch (Exception ex) { } return string.Empty; } private static Dictionary GoodsCacheDic = new Dictionary(); /// /// 清理缓存时间 /// private static DateTime remove_cache_time = DateTime.Now; #region 临时类 class GoodsCahce { public string GoodsSign { get; set; } public DateTime GetTime { get; set; } } #endregion /// /// 缓存异常Cps集合 /// private static Dictionary CacheErrCpsDic = new Dictionary(); /// /// 获取商品高佣信息 /// /// PinduoduoApi对象 /// 推广位pid /// 商品id /// 是否授权绑定 /// public static ArrayList FindSendGuideGoodsInfo(PinduoduoApi api, string pid, string goods_id, bool isBind = false) { #region 清理缓存 if (remove_cache_time.AddHours(5) < DateTime.Now) { remove_cache_time = DateTime.Now; Task.Run(() => { try { var tmps = GoodsCacheDic.Where(f => f.Value.GetTime.AddHours(1) < DateTime.Now).ToList(); if (tmps == null || tmps.Count == 0) return; for (int i = 0; i < tmps.Count; i++) { try { GoodsCacheDic.Remove(tmps[i].Key); } catch (Exception) { } } } catch (Exception) { } }); } #endregion //获取高佣H5信息 var goodsSign = FindGoodsSign_H5(goods_id); if (!string.IsNullOrWhiteSpace(goodsSign)) { try { if (!GoodsCacheDic.ContainsKey(goods_id)) GoodsCacheDic[goods_id] = new GoodsCahce() { GoodsSign = goodsSign, GetTime = DateTime.Now }; } catch (Exception) { } if (!isBind)//true-已绑定;false-未绑定 { //公用的账号 //var guideCps = RandomGuidePddMembers(); //if (guideCps == null) throw new Exception("公共账号异常"); //var guideApi = CpsClient.CreatePinduoduoRequest(guideCps); //if (guideApi == null) throw new Exception("创建公共请求对象异常"); //var fgInfo = FindGoodsInfo(guideApi, goodsSign, guideCps.cookies); //if (fgInfo != null) // return fgInfo; return null; } var goodsInfo = FindGoodsInfo(api, goodsSign, pid); return goodsInfo; } else { PinduoduoApi apiTmp = null; var pidTmp = pid; var cpsUsername = api.Member.username; //无法获取高佣这里获取低佣 for (int i = 0; i < 2; i++) { Dictionary obj_ = null; //if (!isBind)//true-已绑定;false-未绑定 if (CacheErrCpsDic.ContainsKey(cpsUsername) || !isBind)//true-已绑定;false-未绑定 { //公用的账号 //var guideCps = RandomGuidePddMembers(); //if (guideCps == null) throw new Exception("公共账号异常"); //var guideApi = CpsClient.CreatePinduoduoRequest(guideCps); //if (guideApi == null) throw new Exception("创建公共请求对象异常"); //apiTmp = guideApi; //pidTmp = guideCps.cookies; } else apiTmp = api; if (apiTmp == null) continue; try { obj_ = apiTmp.SendPinduoduo("pdd.ddk.oauth.goods.search", new { keyword = goods_id, pid = pidTmp, //custom_parameters = "{\"uid\":\"602172712\",\"sid\":\"jdds\"}" //page = 1, //page_size = 10, //with_coupon = true }); if (obj_ == null) throw new Exception("创建拼多多API请求失败3"); var goods_detail_response = obj_["goods_search_response"] as Dictionary; var goods_list = goods_detail_response["goods_list"] as ArrayList; if (goods_list != null && goods_list.Count != 0) { var tmp = goods_list[0] as Dictionary; if (tmp != null && tmp.Count == 2) return FindGoodsInfo(api, tmp["goods_sign"].ToString(), pid); } return goods_list; } catch (Exception ex) { if (ex.Message.Contains("涉嫌爬虫或本地缓存商品信息")) { CacheErrCpsDic[apiTmp.Member.username] = apiTmp.Member.username; cpsUsername = apiTmp.Member.username; } EventClient.OnEvent(null, $"拼多多:public -> {apiTmp.Member.username} 异常:{ex.Message} - {ex.StackTrace} - {(obj_ == null ? string.Empty : JsonConvert.SerializeObject(obj_))}"); } finally { Thread.Sleep(200); } } } return null; } ///// ///// 获取商品高佣信息 ///// ///// PinduoduoApi对象 ///// 参数 ///// //public static ArrayList FindSendGuideGoodsInfo(PinduoduoApi api, object data) //{ // //公用的账号 // var guideCps = RandomGuidePddMembers(); // if (guideCps == null) throw new Exception("公共账号异常"); // var guideApi = CpsClient.CreatePinduoduoRequest(guideCps); // if (guideApi == null) throw new Exception("创建公共请求对象异常"); // var obj_ = guideApi.SendPinduoduo("pdd.ddk.oauth.goods.search", data); // if (obj_ == null) throw new Exception("创建拼多多API请求失败2"); // //解析商品,获取商品的信息 // var goods_detail_response = obj_["goods_search_response"] as Dictionary; // return goods_detail_response["goods_list"] as ArrayList; //} /// /// 查询商品信息(自己的账号,以保佣金比例的正确性) /// /// PinduoduoApi对象 /// 商品sign /// 推广位pid /// public static ArrayList FindGoodsInfo(PinduoduoApi api, string goods_sign, string pid) { try { var obj_ = api.SendPinduoduo("pdd.ddk.oauth.goods.search", new { goods_sign_list = $"[\"{goods_sign}\"]", pid = pid }); if (obj_ == null) throw new Exception("创建拼多多API请求失败2"); //解析商品,获取商品的信息 var goods_detail_response = obj_["goods_search_response"] as Dictionary; return goods_detail_response["goods_list"] as ArrayList; //var obj_ = api.SendPinduoduo("pdd.ddk.goods.detail", new { goods_sign = goods_sign, pid = pid }); //if (obj_ == null) throw new Exception("创建拼多多API请求失败2"); ////解析商品,获取商品的信息 //var goods_detail_response = obj_["goods_detail_response"] as Dictionary; //return goods_detail_response["goods_details"] as ArrayList; } catch (Exception ex) { } return null; } /// /// 查询商品信息(自己的账号,以保佣金比例的正确性) /// /// PinduoduoApi对象 /// 商品sign /// 推广位pid /// public static ArrayList FindSendGuideGoodsInfo(PinduoduoApi api, object data) { try { var obj_ = api.SendPinduoduo("pdd.ddk.oauth.goods.search", data); if (obj_ == null) throw new Exception("创建拼多多API请求失败2"); //解析商品,获取商品的信息 var goods_detail_response = obj_["goods_search_response"] as Dictionary; return goods_detail_response["goods_list"] as ArrayList; } catch (Exception ex) { } return null; } /// /// 获取拼多多链接中的商品ID /// /// 拼多多商品连接 /// public static string GetPddGoodsID(string url) { bool flag = false; if (url.Contains("goods_id")) flag = true; var _url = HttpExtend.RegexMatchUrl(url); if (!flag && !string.IsNullOrWhiteSpace(_url))//有链接的情况 { //TODO 这里好像还有短连接 目前忘记了短连接的格式 url = _url; if (Regex.IsMatch(url, "(http[s]?://url.cn|http[s]?://a.toutiaonanren.com|http[s]?://p.pinduoduo.com)", RegexOptions.IgnoreCase)) { //可能为短网址//跳转换成真实地址 url = HttpHelper.URLDecode(GetLocation(url)); if (url == null || !url.Contains("goods_id")) return string.Empty; else flag = true; } else flag = true; } if (flag) { var reg = Regex.Match(url, @"goods_sign=(?[^&]{30,70})", RegexOptions.IgnoreCase);//goods_sign=E9f2ompO5KFHjG7BxODcTu-k-n-0MFtO_JeyAMXRb5& if (reg.Success) return reg.Groups["goods_sign"].ToString(); reg = Regex.Match(url, @"goods_id=(?\d{4,})", RegexOptions.IgnoreCase); if (reg.Success) return reg.Groups["good_id"].ToString(); reg = Regex.Match(HttpHelper.URLDecode(url), @"goods_id=(?\d{4,})", RegexOptions.IgnoreCase); if (reg.Success) return reg.Groups["good_id"].ToString(); reg = Regex.Match(HttpHelper.URLDecode(url), @"pinduoduo(?:.*)?goodsId=(?\d{4,})", RegexOptions.IgnoreCase); if (reg.Success) return reg.Groups["good_id"].ToString(); } return string.Empty; } /// /// 获取页面的真实Location的地址(比如:获取短连接的真实地址) /// /// 链接 /// private static string GetLocation(string url) { HttpHelper http = new HttpHelper(); HttpItem item = new HttpItem() { URL = url, Method = "GET", Timeout = 100000, ReadWriteTimeout = 30000, IsToLower = false, Cookie = "", UserAgent = "Opera/9.27 (Windows NT 5.2; U; zh-cn)", Accept = "text/html, application/xhtml+xml, */*", ContentType = "text/html", Referer = "", Postdata = "", }; HttpResult result = http.GetHtml(item); return result.Header.Get("Location"); } /// /// 获取单人团 / 多人团地址 /// /// PinduoduoApi对象 /// 接口的必要参数 /// public string GetShoppingUrl(PinduoduoApi api, object obj) { for (int i = 0; i < 3; i++) { try { var goods_promotion_url_generate_response = api.SendPinduoduo("pdd.ddk.oauth.goods.prom.url.generate", obj)["goods_promotion_url_generate_response"] as Dictionary; var goods_promotion_url_list = goods_promotion_url_generate_response["goods_promotion_url_list"] as ArrayList; string url = string.Empty; foreach (var _url in goods_promotion_url_list) { //return (_url as Dictionary)["short_url"].ToString(); return (_url as Dictionary)["mobile_short_url"].ToString(); } } catch (Exception ex) { } Thread.Sleep(100); } return string.Empty; } /// /// /// /// PinduoduoApi对象 /// 参数 /// public Dictionary GetShoppingUrls(PinduoduoApi api, object obj) { for (int i = 0; i < 2; i++) { try { var goods_promotion_url_generate_response = api.SendPinduoduo("pdd.ddk.oauth.goods.prom.url.generate", obj)["goods_promotion_url_generate_response"] as Dictionary; var goods_promotion_url_list = goods_promotion_url_generate_response["goods_promotion_url_list"] as ArrayList; string url = string.Empty; foreach (var _url in goods_promotion_url_list) { return (_url as Dictionary); } } catch (Exception ex) { EventClient.OnEvent(this, $"生成拼多多推广连接失败:{ex.Message},{ex.StackTrace}"); } Thread.Sleep(100); } return null; } } }