TaobaoOpenPlus.cs 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. using dodohold.core;
  2. using Org.BouncyCastle.Ocsp;
  3. using Sayaka.Common;
  4. using System.Net;
  5. using System.Text.Json;
  6. using System.Xml;
  7. using TencentCloud.Lighthouse.V20200324.Models;
  8. using TencentCloud.Weilingwith.V20230427.Models;
  9. using Top.Api;
  10. using Top.Api.Request;
  11. using Top.Api.Response;
  12. namespace molilian.core
  13. {
  14. public partial class TaobaoOpenPlus
  15. {
  16. public enum RecommendRequestType
  17. {
  18. first,
  19. second,
  20. ori,
  21. }
  22. string _app_key = string.Empty;
  23. string _app_secret = string.Empty;
  24. string _pid = string.Empty;
  25. string _server_url = "https://eco.taobao.com/router/rest";
  26. bool _debug = false;
  27. WebProxy _proxy = null;
  28. public TaobaoOpenPlus(string app_key, string app_secret, string pid, bool debug, WebProxy proxy)
  29. {
  30. _app_key = app_key;
  31. _app_secret = app_secret;
  32. _pid = pid;
  33. _debug = debug;
  34. _proxy = proxy;
  35. }
  36. public static PromotionQueryItemDTO ConverPromotionQueryItem(JsonElement item)
  37. {
  38. PromotionQueryItemDTO result = JsonSerializer.Deserialize<PromotionQueryItemDTO>(item.GetRawText());
  39. string h5_url = item.Read("couponShareUrl", string.Empty);
  40. if (string.IsNullOrEmpty(h5_url))
  41. {
  42. h5_url = item.Read("url", string.Empty);
  43. }
  44. if (h5_url.StartsWith("//")) h5_url = "https:" + h5_url;
  45. result.h5_url = h5_url;
  46. result.deeplink_url = AlimamaPlus.GetDeeplink(h5_url);
  47. if (result.pic.StartsWith("//")) result.pic = "https:" + result.pic;
  48. return result;
  49. }
  50. public TbkThorMfrsPromotionQueryResponse PromotionQueryRequest(string base64, string oaid)
  51. {
  52. var client = new DefaultTopClient(_server_url, _app_key, _app_secret, "json");
  53. client.SetProxy(_proxy);
  54. TbkThorMfrsPromotionQueryRequest req = new();
  55. TbkThorMfrsPromotionQueryRequest.ManufacturerLaunchOptionDomain obj1 = new()
  56. {
  57. Img = base64,
  58. Pid = _pid,
  59. UniqueId = oaid,
  60. UniqueIdType = "oaid",
  61. SceneCode = "h5_img",
  62. SceneSubCode = "Hitoch"
  63. };
  64. req.Option_ = obj1;
  65. TbkThorMfrsPromotionQueryResponse rsp = client.Execute(req);
  66. if (_debug)
  67. {
  68. var _req = req.Convert2Json();
  69. var _rsp = rsp.Convert2Json();
  70. new LoggerLibrary("debug", oaid).Info(_req, _rsp).Save();
  71. }
  72. return rsp;
  73. }
  74. public async Task<(List<PromotionQueryItemDTO>, string, int)> GetRecommendDataWithRetry(
  75. RecommendRequestType type, string oaid,
  76. string cookies,
  77. CancellationToken cancellationToken = default)
  78. {
  79. DateTime stime = DateTime.Now;
  80. // 假设传入了一个 CancellationToken cancellationToken 和 int maxRetries 表示最大重试次数
  81. int retryCount = 0;
  82. int maxRetries = 50;
  83. while (true)
  84. {
  85. try
  86. {
  87. (var data, cookies) = await GetRecommendData(type, oaid, cookies, cancellationToken);
  88. var ts = DateTime.Now - stime;
  89. int elapsedTime = (int)ts.TotalMilliseconds;
  90. return (data, cookies, elapsedTime);
  91. }
  92. catch (Exception ex)
  93. {
  94. if (type == RecommendRequestType.first &&
  95. ex.Message.Equals("RECOMMEND_UNKNOWN_ERROR::Recommend未知错误"))
  96. {
  97. return (new List<PromotionQueryItemDTO>(), cookies, 2);
  98. }
  99. if (retryCount >= maxRetries || cancellationToken.IsCancellationRequested)
  100. {
  101. throw;
  102. }
  103. retryCount++;
  104. await Task.Delay(100);
  105. }
  106. }
  107. }
  108. public async Task<(List<PromotionQueryItemDTO>, string)> GetRecommendData(RecommendRequestType type, string oaid,
  109. string cookies, CancellationToken cancellationToken = default)
  110. {
  111. string token = "undefined";
  112. if (!string.IsNullOrEmpty(cookies)) token = cookies.GetContentPart("_m_h5_tk=", "_");
  113. string url = GetRecommendUrl(_pid, oaid, token, type);
  114. string body = string.Empty;
  115. string ua = ProviderFakeUserAgent.RandomMobile;
  116. var client = new WebClientUtility();
  117. client.Proxy = _proxy;
  118. client.UserAgent = ua;
  119. if (string.IsNullOrEmpty(cookies))
  120. {
  121. var res = await client.RequestAsync(url, "GET", cancellationToken);
  122. if (!res.Successed) { throw res.ResponseException; }
  123. body = res.Body();
  124. if (_debug)
  125. {
  126. new LoggerLibrary("debug", oaid)
  127. .Info("第一次 cookies 初始化")
  128. .Info(ua, _proxy?.Address?.AbsoluteUri)
  129. .Info(url, body)
  130. .Save();
  131. }
  132. cookies = res.ResponseMessage.GetCookiesString();
  133. token = cookies.GetContentPart("_m_h5_tk=", "_");
  134. }
  135. url = GetRecommendUrl(_pid, oaid, token, type);
  136. client = new WebClientUtility();
  137. client.Proxy = _proxy;
  138. client.UserAgent = ua;
  139. if (!string.IsNullOrEmpty(cookies)) client.SetCookies(cookies);
  140. var response = await client.RequestAsync(url, "GET", cancellationToken);
  141. body = response.Body();
  142. if (_debug)
  143. {
  144. new LoggerLibrary("debug", oaid)
  145. .Info("GetRecommendData")
  146. .Info(ua, _proxy?.Address?.AbsoluteUri)
  147. .Info(url, cookies)
  148. .Info(body)
  149. .Save();
  150. }
  151. body = body.Trim().StringTrimStart("mtopjsonp1(");
  152. body = body.StringTrimEnd(")");
  153. var root = body.Convert2JsonElement();
  154. var ret = root.PathRead("ret[0]", string.Empty);
  155. if (!"SUCCESS::调用成功".Equals(ret))
  156. {
  157. throw new Exception(ret);
  158. }
  159. var resultList = new List<PromotionQueryItemDTO>();
  160. foreach (var data in root.ElementRead("data").ElementRead("resultList").EnumerateArray())
  161. {
  162. PromotionQueryItemDTO item = ConverPromotionQueryItem(data);
  163. resultList.Add(item);
  164. }
  165. return (resultList, cookies);
  166. }
  167. public string GetRecommendUrl(string pid, string oaid, string token, RecommendRequestType type)
  168. {
  169. var first_data = $"{{\"scene\":\"pltSimilarPromotion\",\"variableMap\":\"{{\\\"pid\\\":\\\"{pid}\\\",\\\"oaid\\\":\\\"{oaid}\\\",\\\"type\\\":\\\"first\\\"}}\"}}";
  170. var second_data = $"{{\"scene\":\"pltSimilarPromotion\",\"variableMap\":\"{{\\\"pid\\\":\\\"{pid}\\\",\\\"oaid\\\":\\\"{oaid}\\\",\\\"type\\\":\\\"second\\\"}}\"}}";
  171. var ori_data = $"{{\"scene\":\"pltPromotionImg\",\"variableMap\":\"{{\\\"pid\\\":\\\"{pid}\\\",\\\"oaid\\\":\\\"{oaid}\\\",\\\"hasCoupon\\\":false,\\\"filterType\\\":\\\"ori\\\",\\\"seq\\\":\\\"\\\"}}\"}}";
  172. string ts = DateTime.Now.Convert2UnixTimestamp(true).ToString();
  173. string data = type switch
  174. {
  175. RecommendRequestType.first => first_data,
  176. RecommendRequestType.second => second_data,
  177. _ => ori_data,
  178. };
  179. string sign = GetSign(token, ts, data);
  180. string url = $"https://h5api.m.taobao.com/h5/mtop.union.thor.landing.page.recommend/1.0/" +
  181. $"?jsv=2.4.16&appKey=12574478&t={ts}&sign={sign}&v=1.0&api=mtop.union.thor.landing.page.recommend" +
  182. $"&timeout=20000&AntiCreep=true&AntiFlood=true&type=jsonp&dataType=jsonp&callback=mtopjsonp1" +
  183. $"&data={data.UrlEncode()}";
  184. return url;
  185. }
  186. private string GetSign(string token, string ts, string data)
  187. {
  188. string g = "12574478";
  189. //%7B%22scene%22%3A%22pltPromotionImg%22%2C%22variableMap%22%3A%22%7B%5C%22pid%5C%22%3A%5C%22mm_5993059531_3080100059_115689750259%5C%22%2C%5C%22oaid%5C%22%3A%5C%22-7775661578900138800%5C%22%2C%5C%22hasCoupon%5C%22%3Afalse%2C%5C%22filterType%5C%22%3A%5C%22ori%5C%22%2C%5C%22seq%5C%22%3A%5C%22%5C%22%7D%22%7D
  190. //%7B%22scene%22%3A%22pltPromotionImg%22%2C%22variableMap%22%3A%22%7B%5C%22pid%5C%22%3A%5C%22mm_5993059531_3080100059_115689750259%5C%22%2C%5C%22oaid%5C%22%3A%5C%22-7775661578900138800%5C%22%2C%5C%22hasCoupon%5C%22%3Afalse%2C%5C%22filterType%5C%22%3A%5C%22ori%5C%22%2C%5C%22seq%5C%22%3A%5C%22%5C%22%7D%22%7D
  191. var signString = $"{token}&{ts}&{g}&{data}";
  192. return signString.MD5();
  193. }
  194. }
  195. }