using Api.Framework.Cps;
using Api.Framework.Model;
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;
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;
else
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;
}
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;
}
///
/// 获取拼多多链接中的商品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_id=(?\d{4,})");
if (reg.Success)
return reg.Groups["good_id"].ToString();
reg = Regex.Match(HttpHelper.URLDecode(url), @"goods_id=(?\d{4,})");
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;
}
}
}