using AllBase; using AllBase.Helper; using NaiBa.Util; using NaiBa.Util.Extension; using NaiBa.Util.Helper; using System; using System.Collections.Generic; using System.IO; using System.IO.Compression; using System.Linq; using System.Net; using System.Text; using System.Text.RegularExpressions; using WebSocketSharp; namespace Work.CollectClass { /* * 调用示例: ProductCollectBase pb = new ProductCollectBase(); pb.from_id=132465123; pb.from_url = "https://item.m.jd.com/product/" + skuID + ".html"; JingXiCollect tm = new JingXiCollect(pb); tm.Get(); var p = tm.Product; */ public class JingXiCollect { /// /// 已经下架的商品集合 /// public static List DeleteIds = new List(); public static bool IsIpOver = false; public static List listIp = null; /// /// 验证码URL,如果有值,代表需要用户输入验证码,进行验证。 /// public static string VerifyCodeUrl = ""; public string Name = "发布商品"; public bool IsOnSale = true; public bool IsUseProxy = false;//是否使用代理ip public bool IsVerify = false; // 京喜采集是否受限 public ProductCollectBase Product; public GoodsStatusEnum GoodsStatus = GoodsStatusEnum.NotExist; /// /// 是否使用服务器缓存 /// private static bool UseServerCache = true; // 开发专用,当缓存服务器出故障时,设置为false,调试代码专用 private int IpListCount = 0; /// /// 拼购商品拼购价格字典(商品详情中已无拼购价格信息) /// private Dictionary dicPinGouPrice = new Dictionary(); public JingXiCollect(ProductCollectBase product) { this.Product = product; } public void Get() { this.GoodsStatus = GoodsStatusEnum.NotExist; if (JingXiCollect.VerifyCodeUrl.Length > 0) return; //判断商品是否下架 if (JingXiCollect.DeleteIds.Contains(this.Product.from_id)) { LogSave.Add(this.Name, "商品已经下架:" + Product.from_id); IsOnSale = false; return; } //采集历史缓存 if (TaobaoMobileCollect.ProductTemp.ContainsKey(Product.from_id)) { this.Product = TaobaoMobileCollect.ProductTemp[Product.from_id].Clone(); this.GoodsStatus = GoodsStatusEnum.Exist; return; } SkuInfo sm = GetSkuInfo(this.Product.from_id); if (sm.msg.Contains("404")) { JingXiCollect.DeleteIds.Add(this.Product.from_id); LogSave.Add(this.Name, "商品已经下架:" + Product.from_id); IsOnSale = false; return; } if (sm.msg.Contains("proxyCount")) { JingXiCollect.VerifyCodeUrl = "代理ip已用完"; return; } if (sm.msg.Contains("获取京喜商品详情失败")) { this.IsVerify = true; return; } if (sm.msg.Contains("spider_check.shtml")) { JingXiCollect.VerifyCodeUrl = sm.msg;//通知前端,当前端收到此信息后,可以弹出验证界面,获取cookie--后续继续验证 return; } this.Product.id = this.Product.from_id; this.Product.from_url = "https://item.m.jd.com/product/" + this.Product.from_id + ".html"; string pName = sm.PName.RemoveSpecialChar(":", ":", "/", "\\", "\"", "?", "✅", "◆", "‼️"); //【XX进口】【XX直邮】【XX直供】不可以填入商品标题中,请修改后重新操作【XX进口】【XX直邮】【XX直供】不可以填入商品标题中,请修改后重新操作 //pName = BaseRegex.Relpace(pName, "【.*?】", ""); this.Product.name = pName;//商品名称 this.Product.from_title = pName;//商品标题 this.Product.image = sm.Image;//第一张轮播图 this.Product.image_from_url = sm.Image;//第一张轮播图 this.Product.Images = sm.ImageList;//轮播图 this.Product.content = sm.DetailImageListHTML.Replace("http://img", "//img"); this.Product.express_price = sm.ExpressPrice;//运费 this.Product.price = sm.SellPrice;// 售价:如果是拼购的,则是拼购价格;如果没有拼购,则是原价 this.Product.before_price = sm.BeforePrice;//原价 this.Product.num = (int)sm.SaleNum;//销量 this.Product.saleCount = (int)sm.SaleNum;//销量 this.Product.from_shop_name = sm.ShopName;//店铺名称 this.Product.discountPrice = sm.PinGouPrice;//折扣价格 this.Product.discount = sm.PinGouPrice / sm.BeforePrice;//折扣比例:= 折扣价格 / 原价 this.Product.onlinePrice = Product.discountPrice * Product.shopAddPercent / 100 + new Random(Guid.NewGuid().GetHashCode()).Next((int)(Product.shopAddPriceMin * 100), (int)(Product.shopAddPriceMax * 100)) / 100; this.Product.state = sm.Province;//省份 this.Product.city = sm.City;//城市 this.Product.from_site_id = 4;//京喜,约定的 this.Product.from = "京喜"; this.Product.from_name = pName; //this.Product.VideoId = sm.MainVideoId;//视频ID this.Product.upShopId = sm.ShopId;//上家ID this.Product.Prop = sm.Prop;//详情属性 //现货:33 //有货:39 or 40 //预定,采购中:36 //无货:其他 if (sm.StockState == 36) this.Product.logisticsTime = "预售";//发货时间 //this.Product.main_cat_name = ""; //Content:正文:包含正文图片:针对img的集合 //item_size =“” //item_weight = 1 if (sm.Categorys.Count > 0) this.Product.cat1 = sm.Categorys[0]; if (sm.Categorys.Count > 1) this.Product.cat2 = sm.Categorys[1]; if (sm.Categorys.Count > 2) this.Product.cat3 = sm.Categorys[2]; if (sm.Categorys.Count > 3) this.Product.cat4 = sm.Categorys[3]; if (sm.Categorys.Count > 0) { this.Product.main_cid = sm.Categorys[0]; this.Product.cat_id = sm.Categorys[sm.Categorys.Count - 1]; this.Product.from_cat_id = sm.Categorys[sm.Categorys.Count - 1]; } this.Product.Props = sm.Props; //Sku this.Product.SkuMaps.Clear(); foreach (var x in sm.SkuDetailList) { SkuInfo sku = null; if (x.skuId == sm.SkuId)//已经获取过了,不必重新获取 sku = sm; else sku = GetSkuInfo(x.skuId); if (sku.msg.Contains("spider_check.shtml")) { JingXiCollect.VerifyCodeUrl = sku.msg;//通知前端,当前端收到此信息后,可以弹出验证界面,获取cookie--后续继续验证 return; } this.Product.SkuMaps.Add(new SkuMapBase() { name = sku.SkuNameExt, //nameLite = "",//此处不需要赋值,自动从name进行赋值 //price = sku.PinGouPrice,//经确认,拼团价为基础价格 2020.6.15 price = sku.SellPrice,//经确认,拼团价为基础价格 2020.6.15 number = (sku.StockStateName == "无货" ? 0 : sku.StockNumber), //new Random(Guid.NewGuid().GetHashCode()).Next(100, 1000),//库存 before_price = sku.BeforePrice, sale_count = (int)sku.SaleNum, //online_price = (int)sku.BeforePrice,//单买价 //new_price = (int)sku.PinGouPrice,//团购价 prop_image = sku.Image }); } ///拼多多只支持2级属性,所以,要将多余2级的属性转换到2级 ///参考:淘宝上拼多多的方式:做减法 if (this.Product.Props.Count > 2)//2级以内属性 { //处理Props:参考淘宝的做法,取属性个数最多的两个Prop this.Product.Props = sm.Props.OrderByDescending(u => u.Values.Count).ToList(); this.Product.Props.RemoveRange(2, this.Product.Props.Count - 2); //将多余的SkuMaps删除 List skuMaps = new List(this.Product.SkuMaps); this.Product.SkuMaps.Clear(); for (int i = 0; i < skuMaps.Count; i++) { SkuMapBase sku = skuMaps[i]; List listName = new List(); string[] arrsku = sku.name.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries); foreach (var str in arrsku) { string propNames = str.Split(':')[0]; if (this.Product.Props.Exists(o => o.name == propNames)) listName.Add(str); } //修改name:将蝶羽白;全网通(6GB 128GB);官方标配 ==>蝶羽白;全网通(6GB 128GB) sku.name = string.Join(";", listName); if (!this.Product.SkuMaps.Exists(o => o.name == sku.name)) this.Product.SkuMaps.Add(sku); } } foreach (var p in Product.Props) { if (sm.Props.Any(pr => pr.name == "颜色")) { if (p.name == "颜色") { foreach (var v in p.Values) { var sku = Product.SkuMaps.FirstOrDefault(s => (s.name + ";").Contains(":" + v.name + ";")); if (sku != null) { v.image = sku.prop_image; } } } else continue; } else { foreach (var v in p.Values) { var sku = Product.SkuMaps.FirstOrDefault(s => (s.name + ";").Contains(":" + v.name + ";")); if (sku != null) { v.image = sku.prop_image; } } break; } } //采集历史缓存集合 if (TaobaoMobileCollect.ProductTemp.Count > 1000)//删除最早的一条记录 { var v = TaobaoMobileCollect.ProductTemp.First(); TaobaoMobileCollect.ProductTemp.Remove(v.Key); } if (TaobaoMobileCollect.ProductTemp.ContainsKey(this.Product.from_id)) TaobaoMobileCollect.ProductTemp.Remove(this.Product.from_id); TaobaoMobileCollect.ProductTemp.Add(this.Product.from_id, this.Product); //所有采集完毕,标识商品有货,可用 this.GoodsStatus = GoodsStatusEnum.Exist; } public static string requestJDCom(string url, string refere, bool isUtf8, string data, string agentIp, string sCookies = "") { try { string domain = GetHtml.GetDomain(url); string mainDomain = GetHtml.GetMainDomain(domain); string cookies = sCookies; if (sCookies.Length == 0) { if (BaseClass.CookiesAllString.ContainsKey(mainDomain)) cookies = BaseClass.CookiesAllString[mainDomain]; else if (BaseClass.CookiesAllString.ContainsKey(domain)) cookies = BaseClass.CookiesAllString[domain]; } string userAgent = BaseClass.ChromeUserAgent; userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36"; AllBase.WebClientx wb = new AllBase.WebClientx(); wb.Timeout = 30; wb.AllowAutoRedirect = true; wb.Headers.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"); //wb.Headers.Add("X-Requested-With", "XMLHttpRequest"); wb.Headers.Add("Accept-Encoding", "gzip,deflate"); wb.Headers.Add("Accept-Language", "zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3"); wb.Headers.Add("User-Agent", userAgent); if (!string.IsNullOrEmpty(refere)) wb.Headers.Add("Referer", refere); if (!string.IsNullOrEmpty(cookies)) wb.Headers.Add("Cookie", cookies); wb.Proxy = null; if (!string.IsNullOrEmpty(agentIp)) { WebProxy proxy = new WebProxy(); proxy.Address = new Uri(string.Format("http://{0}:{1}", agentIp.Split(':')[0], agentIp.Split(':')[1])); wb.Proxy = proxy; } string rehead = wb.Headers.ToString(); var encode = isUtf8 ? Encoding.UTF8 : Encoding.GetEncoding("gbk"); byte[] b, postData = data == null ? new byte[0] : encode.GetBytes(data); string html, head; try { if (string.IsNullOrEmpty(data)) { b = wb.DownloadData(url); } else { wb.Headers.Add("Content-Type", "application/x-www-form-urlencoded"); wb.Headers.Add("ContentLength", postData.Length.ToString()); b = wb.UploadData(url, "POST", postData); } html = encode.GetString(b); string c = BaseRegex.GetMatchRegexString(wb.ResponseHeaders["Content-Type"], "charset\\s*=\\s*(\\S+)"); if (!string.IsNullOrEmpty(c)) { c = c.Trim().ToLower().Replace("utf8", "utf-8"); } if (string.IsNullOrEmpty(c)) c = BaseRegex.GetMatchRegexString(html, @"]*?charset=[""']*([\w-]+)[""']*"); if (!string.IsNullOrEmpty(c)) { if (c.IndexOf("'") > -1) c = c.Substring(0, c.IndexOf("'")); if (c.IndexOf("\"") > -1) c = c.Substring(0, c.IndexOf("\"")); if (c.IndexOf(" ") > -1) c = c.Substring(0, c.IndexOf(" ")); if (c.IndexOf(">") > -1) c = c.Substring(0, c.IndexOf(">")); if (!string.IsNullOrEmpty(c)) html = Encoding.GetEncoding(c).GetString(b); } head = wb.ResponseHeaders.ToString(); } catch (Exception ee) { html = "提交错误:" + ee.Message; head = ""; } return GetHtml.Decode(html); } catch (Exception e) { LogSave.Add("访问网址错误:" + url + " " + e.Message); return ""; } } private string getSkuHtml(long skuid, ref bool canUse) { ///获取html数据,获取途径: ///1,服务器缓存html ///2,直接获取html canUse = false; string html = ""; if (JingXiCollect.UseServerCache) html = ServerTemp.Get(5, skuid.ToString(), out canUse); string url = "https://item.m.jd.com/item/mview2?datatype=1&callback=skuInfoCBC&cgi_source=mitem&sku=" + skuid; string refer = "https://item.m.jd.com/product/" + skuid + ".html"; refer = ""; if (!canUse) { html = ""; //html = AllBase.GetHtml.GetUtf8(url, AllBase.BaseClass.ChromeUserAgent); if (!IsUseProxy) { html = Work.GetPostTaobaoHtml.GetUrl(url, refer, false, ""); System.Threading.Thread.Sleep(Randomx.GetId(1000, 2000)); } string redirect_Url = AllBase.BaseRegex.GetStringJson(ref html, "redirectUrl"); if (redirect_Url != null && redirect_Url.Length > 0 && !IsUseProxy) { refer = "https://wqs.jd.com/"; refer = ""; url = "https://m.jingxi.com/item/view?_fd=jdm&sku=" + skuid + "&mitemdomain=item.m.jd.com&datatype=1&callback=skuInfoCBC&cgi_source=mitem"; var htmlx = Work.GetPostTaobaoHtml.GetUrl(url, refer, false, ""); System.Threading.Thread.Sleep(Randomx.GetId(1000, 2000)); var htmlData = BaseRegex.GetMatchMaxRegexString(ref htmlx, "window._itemInfo = \\(([\\s\\S]+?)"); if (!string.IsNullOrEmpty(htmlData) && htmlData.Contains("\"skuId\":\"" + skuid + "\"")) { html = "skuInfoCBC(" + htmlData.Trim(' ', '\n', '\r', ';', 'r') + ")"; } else { //html = "获取京喜商品详情失败"; this.IsVerify = true; } } } string skuInfoCBC = "" + BaseRegex.GetMatchRegexString(ref html, "skuInfoCBC\\((\\{[\\w\\W]*\\})\\)"); //redirectUrl: "//m.jd.com/404.htm?errcode=10001" string redirectUrl = "" + AllBase.BaseRegex.GetStringJson(ref skuInfoCBC, "redirectUrl"); string errCode = "" + AllBase.BaseRegex.GetStringJson(ref skuInfoCBC, "errCode"); if ((string.IsNullOrEmpty(html) || !string.IsNullOrWhiteSpace(redirectUrl) || errCode == "20001") && IsUseProxy) // 请求出现验证的时候 并且使用代理 { if (listIp != null && listIp.Count > IpListCount && listIp[IpListCount] != null) { html = requestJDCom(url, refer, false, "", listIp[IpListCount]); skuInfoCBC = BaseRegex.GetMatchRegexString(ref html, "skuInfoCBC\\((\\{[\\w\\W]*\\})\\)"); redirectUrl = AllBase.BaseRegex.GetStringJson(ref skuInfoCBC, "redirectUrl"); if (string.IsNullOrEmpty(redirectUrl) && html.Contains("提交错误")) { LogHelper.WriteWithTime(" 代理ip:" + listIp[IpListCount] + "请求失败" + html); } else { LogHelper.WriteWithTime(" 代理ip:" + listIp[IpListCount] + "redirectUrl参数:" + redirectUrl); } } } return html; } /// /// 根据获取到的html 读取sku /// /// /// private SkuInfo GetSkuInfo(long skuid) { int getHtmlCount = 0; reGetHtml: SkuInfo sku = new SkuInfo(); if ((listIp == null || listIp.Count == 0) && IsUseProxy) { bool bo = false; listIp = BLL.Collect.PddSameScreeningBLL.InitIp(GetProxyHtml.txtUrl, out bo); if (bo) { IsIpOver = true; sku.msg = "请检查ip套餐是否过期"; } } bool canUse = false; var html = getSkuHtml(skuid, ref canUse); if (html == "获取京喜商品详情失败") { sku.msg = "获取京喜商品详情失败"; } sku.SkuId = skuid; string skuInfoCBC = "" + BaseRegex.GetMatchRegexString(ref html, "skuInfoCBC\\((\\{[\\w\\W]*\\})\\)"); //redirectUrl: "//m.jd.com/404.htm?errcode=10001" if (string.IsNullOrEmpty(skuInfoCBC) && html.Contains("window._itemInfo = ")) { var htmlData = BaseRegex.GetMatchMaxRegexString(ref html, "window._itemInfo = \\(([\\s\\S]+?)"); if (!string.IsNullOrEmpty(htmlData) && htmlData.Contains("\"skuId\":\"" + skuid + "\"")) { skuInfoCBC = "skuInfoCBC(" + htmlData.Trim(' ', '\n', '\r', ';', 'r') + ")"; } } string redirectUrl = "" + AllBase.BaseRegex.GetStringJson(ref skuInfoCBC, "redirectUrl"); if (string.IsNullOrEmpty(sku.msg) && !string.IsNullOrEmpty(redirectUrl)) sku.msg = redirectUrl; if (html.Contains("提交错误") && getHtmlCount <= 10) { getHtmlCount++; if (listIp.Count > IpListCount) listIp.RemoveAt(IpListCount); goto reGetHtml; } if (html.Contains("该商品已下架")) { sku.msg = "404"; return sku; } if (sku.msg.Length > 0 && IsUseProxy && getHtmlCount <= 10)//取不到值 并且是代理的情况下 { getHtmlCount++; if (listIp.Count > IpListCount) listIp.RemoveAt(IpListCount); goto reGetHtml; } if (sku.msg.Length > 0) return sku; sku.SkuName = AllBase.BaseRegex.GetStringJson(ref skuInfoCBC, "skuName"); sku.PName = AllBase.BaseRegex.GetStringJson(ref skuInfoCBC, "pName"); sku.Image = AllBase.BaseRegex.GetStringJson(ref skuInfoCBC, "image")?.Replace("\\x2F", "/").Replace("!q80.dpg.webp", ""); if (string.IsNullOrEmpty(sku.Image)) { var img = BaseRegex.GetMatchRegexString(ref skuInfoCBC, "\"image\":\\[([\\s\\S]+?)\\],"); if (!string.IsNullOrEmpty(img)) img = img.Split(',')[0].Trim('"'); sku.Image = "//m.360buyimg.com/mobilecms/s750x750_" + img; } sku.BrandName = AllBase.BaseRegex.GetStringJson(ref skuInfoCBC, "brandName"); sku.BrandId = AllBase.BaseRegex.GetStringJson(ref skuInfoCBC, "brandId"); sku.PromiseMark = AllBase.BaseRegex.GetStringJson(ref skuInfoCBC, "promiseMark"); sku.StockState = AllBase.BaseRegex.GetIntJson(ref skuInfoCBC, "StockState"); sku.StockStateName = AllBase.BaseRegex.GetStringJson(ref skuInfoCBC, "StockStateName"); sku.StockNumber = AllBase.BaseRegex.GetIntJson(ref skuInfoCBC, "eb"); sku.ShopName = AllBase.BaseRegex.GetStringJson(ref html, "vender"); sku.ShopId = AllBase.BaseRegex.GetMatchMaxRegexString(ref html, "\"deliver\":\".+?\",\"id\":(\\d+)").ParseToLong(); sku.Deliver = AllBase.BaseRegex.GetStringJson(ref html, "deliver"); sku.DeliverAddress = AllBase.BaseRegex.GetStringJson(ref html, "df"); // sku.MainVideoId = AllBase.BaseRegex.GetStringJson(ref skuInfoCBC, "mainVideoId"); //208594505 sku.ExpressPrice = AllBase.BaseRegex.GetIntJson(ref html, "dcash"); //0 sku.Prop = GetSpecification(skuid); //0 string description = AllBase.BaseRegex.GetStringJson(ref html, "description"); //d14676910654 sku.DetailImageList = GetDetailImageList(skuid, description); sku.DetailImageList.ForEach(s => { sku.DetailImageListHTML += ""; }); KeyValueBase city = GetProvince_City(sku.DeliverAddress); sku.Province = city.Value;//省份 sku.City = city.Key;//城市 //sku.ImageList string skuInfoCBC_image = AllBase.BaseRegex.GetMatchRegexString(skuInfoCBC, "\\\"image\\\":\\[([\\w\\W]+?)]"); //"jfs/t1/112057/35/11816/136894/5f02c690Ef42f3746/f0c2d6365e028db7.jpg","jfs/t1/148525/31/2184/264063/5f02c685E427bd5c4/1f68bac7953fb631.jpg","jfs/t1/119092/12/11639/206907/5f02c685Ea46ebbfb/10c636358954a177.jpg","jfs/t1/121822/14/6363/214792/5f02c686Ea06c2de9/4f93b4878596a225.jpg","jfs/t1/117172/7/11523/199385/5f02c686E9e1163d4/eada4b07f5fa2759.jpg","jfs/t1/116907/29/11607/208292/5f02c687Ef7079f1b/dc24acfd8b6fd2fc.jpg","jfs/t1/121655/30/6391/182266/5f02c687E7219652e/c18b7cb772e87d7c.jpg","jfs/t1/118719/11/11664/194853/5f02c687Eceeb21a7/910afece15570ce9.jpg","jfs/t1/143578/32/2242/221134/5f02c688E1830c8e9/7c399c424fe58509.jpg","jfs/t1/116031/38/11700/152479/5f02c689Ec4f9cdd6/9d949560bd3788aa.jpg" if (skuInfoCBC_image != null) { new List(skuInfoCBC_image.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries)).ForEach(s => { sku.ImageList.Add("https://m.360buyimg.com/ceco/" + s.Replace("\"", "")); }); } //sku.SkuDetailList var skuInfoCBC_newColorSize = AllBase.BaseRegex.GetMatchRegex(html, "\\{(\\\"dim\\\":[\\s\\S]+?)\\}");// 出现 if (skuInfoCBC_newColorSize.Count == 0) skuInfoCBC_newColorSize = BaseRegex.GetMatchRegex(html, "\\{(\\\"sequenceNo2\\\":[\\s\\S]+?)\\}"); foreach (Match m in skuInfoCBC_newColorSize) { string item = m.Value; SkuInfo.SkuInfoDetail detail = new SkuInfo.SkuInfoDetail() //{"dim":3,"sequenceNo1":"12","sequenceNo2":"1","sequenceNo3":"0","1":"小款变形手表(绿巨人)","2":"均码","3":"","SpecName":"","skuId":"71389595614"} { skuId = AllBase.BaseRegex.GetLongJson(ref item, "skuId"), //"小款变形手表(绿巨人)" Prop1 = AllBase.BaseRegex.GetStringJson(ref item, "1"), //"均码" Prop2 = AllBase.BaseRegex.GetStringJson(ref item, "2"), //"" Prop3 = AllBase.BaseRegex.GetStringJson(ref item, "3") //71389595614 }; sku.SkuDetailList.Add(detail); } // 获取价格(因原接口无法获取拼购价,需要使用sku列表获取单独的拼购价格,将价格获取放到sku列表获取后) sku.BeforePrice = BaseRegex.GetDecimalJson(ref skuInfoCBC, "op");//原价 sku.PinGouPrice = BaseRegex.GetDecimalJson(ref skuInfoCBC, "bp");//拼购价 // 获取所有sku的拼购价格 if (sku.PinGouPrice == 0 && dicPinGouPrice.Keys.Count == 0) { if (BaseClass.UserName == "18355183710") FileBase.WriteAllText("pingou_html.txt", "pingou_info: "); //var shops = GlobalConfig.JDShopLoginList.Where(s => s.LoginStatus == "登录成功").ToList(); //var shop = shops.Count > 0 ? shops[Randomx.GetId(shops.Count)] : new LittleCow.Model.Result.JDShopLoginInfo() //{ // Cookies = @"1BAE23EC9D9791A1474EC42D7F7F8C83B7231A71F615C334906B0C3758FA60CABDE9502205933B0331B61610000AF0F9D0125204144AA5AB85D21A72BD6584849C2900A7B54574A9DC4A0DB96997B6C6909A236512E657BF74EA85E8CD750D055C6EACA03A7A45A03A801C2AB8EC11C78BB83B2E1736FF837978DA5B46D1DC999478FBA07B98566A44F74DBD9974339C", //}; var Cookies = @"1BAE23EC9D9791A1474EC42D7F7F8C83B7231A71F615C334906B0C3758FA60CABDE9502205933B0331B61610000AF0F9D0125204144AA5AB85D21A72BD6584849C2900A7B54574A9DC4A0DB96997B6C6909A236512E657BF74EA85E8CD750D055C6EACA03A7A45A03A801C2AB8EC11C78BB83B2E1736FF837978DA5B46D1DC999478FBA07B98566A44F74DBD9974339C"; string skuIdStr = ""; for (int i = 0; i < sku.SkuDetailList.Count; i++) { skuIdStr += sku.SkuDetailList[i].skuId + ","; if ((i + 1) % 20 == 0 || i == sku.SkuDetailList.Count - 1) { //var cookie = shop.Cookies; var cookie = Cookies; string url = "https://m.jingxi.com/pingou_api/getskusprice?skuids=" + skuIdStr.TrimEnd(','); string refer = ""; var pingouHtml = GetPostTaobaoHtml.GetUrl(url, refer, false, "", cookie); if (BaseClass.UserName == "18355183710") FileBase.AppendAllText("pingou_html.txt", pingouHtml); System.Threading.Thread.Sleep(Randomx.GetId(500, 1500)); if (string.IsNullOrEmpty(pingouHtml) || !pingouHtml.Contains("\"bp\"") || !pingouHtml.Contains("\"op\"") || !pingouHtml.Contains("\"id\"")) pingouHtml = GetPostTaobaoHtml.GetUrl(url, refer, false, "", cookie); System.Threading.Thread.Sleep(Randomx.GetId(500, 1500)); if (!string.IsNullOrEmpty(pingouHtml)) { var pingouArr = pingouHtml.Split('{'); foreach (var txt in pingouArr) { var t = txt; if (txt.Contains("\"bp\"") && txt.Contains("\"op\"") && txt.Contains("\"id\"")) { var pingou_id = BaseRegex.GetStringJson(ref t, "id"); var pingou_bp = BaseRegex.GetStringJson(ref t, "bp"); this.dicPinGouPrice[pingou_id] = pingou_bp; } } } skuIdStr = ""; } } } if (sku.PinGouPrice == 0 && dicPinGouPrice.ContainsKey(sku.SkuId.ToString())) { sku.PinGouPrice = dicPinGouPrice[sku.SkuId.ToString()].ParseToDecimal(); if (sku.PinGouPrice > 0 && !html.Contains("\"bp\"") && html.Contains("\"op\"")) { //canUse = false; html = html.Replace("\"op\"", "\"bp\":\"" + dicPinGouPrice[sku.SkuId.ToString()] + "\",\"op\""); } } if (sku.PinGouPrice > 0)//有拼购,销售价格为拼购价格 { sku.SellPrice = sku.PinGouPrice; sku.SaleNum = this.GetPinTuanCount(sku.SkuId);//获取拼团的销量 //string pingou_member_count = AllBase.BaseRegex.GetStringJson(ref skuInfoCBC, "pingou_member_count"); //sku.SaleNum = this.Unit_Conversion(pingou_member_count); } else//没有拼购,则销售价格为市场价格 { sku.SellPrice = AllBase.BaseRegex.GetDecimalJson(ref skuInfoCBC, "p");//市场价 sku.SaleNum = this.GetGoodCount(sku.SkuId);//获取单购的销量 } //sku.Categorys string category = AllBase.BaseRegex.GetMatchRegexString(ref skuInfoCBC, "category\":\\[(.+?)\\]"); //"1672","2599","5266" if (!category.IsNullOrEmpty()) { new List(category.Split(new string[] { ",", "\"" }, StringSplitOptions.RemoveEmptyEntries)).ForEach(s => { sku.Categorys.Add(s.ParseToInt()); }); } //sku.Props string saleProp = AllBase.BaseRegex.GetMatchRegexString(ref skuInfoCBC, "saleProp\":\\{(.+?)\\}").Replace("\"", ""); //"1:颜色,2:款式,3:" new List(saleProp.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries)).ForEach(s => { int propId = s.Split(':')[0].ParseToInt(); string propName = s.Split(':')[1]; if (!string.IsNullOrEmpty(propName)) { sku.Props.Add(new PropBase() { id = propId, name = propName, sort = propId }); } }); //sku.Props.Values string salePropSeq = AllBase.BaseRegex.GetMatchRegexString(ref skuInfoCBC, "salePropSeq\":\\{(.+?)\\}"); //"1":["蓝色奥特曼(可变形可投影)","蜘蛛侠(可变形可投影)","钢铁侠(可变形可投影)","蝙蝠侠(可变形可投影)","绿巨人(可变形可投影)","美国队长(可变形可投影)","冰雪奇缘(可变形可投影)","变形金刚(可变形可投影)","小款变形手表(宝石蓝)没投影","小款变形手表(火焰红)没投影","小款变形手表(没投影)","小款变形手表(绿巨人)"],"2":["均码"],"3":[""] var mm = AllBase.BaseRegex.GetMatchRegex(salePropSeq, "\"(\\d+)\":\\[(.*?)\\]"); var imgMatchList = new List(); try { var imgMatchStr = BaseRegex.GetMatchRegexString(ref skuInfoCBC, "\"pingou\":([\\s\\S]+?)\"daojia\""); var imgMatch = BaseRegex.GetMatchRegex(ref imgMatchStr, "\"imagePath\":\"([\\s\\S]*?)\"select\""); imgMatchList.AddRange(imgMatch.Cast().Select(m => m.ToString()).ToList()); } catch { } foreach (Match v in mm) { int v1 = v.Groups[1].Value.ParseToInt(); var p = sku.Props.Find(o => o.id == v1); if (p == null) continue; string[] v2 = v.Groups[2].Value.Replace("\"", "").Replace("[", "").Replace("]", "").Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < v2.Length; i++) { var pv = new PropValueBase() { id = i.ToString(), value = v2[i], name = v2[i] }; var image = imgMatchList.FirstOrDefault(im => im.Contains("\"" + pv.name + "\"")); image = BaseRegex.GetStringJson(ref image, "imagePath"); //m.360buyimg.com/mobilecms/s800x800_jfs/t1/120893/26/6529/254083/5f03e2bdE25f7e708/3539b3d189167c32.jpg!q80.dpg if (!string.IsNullOrEmpty(image)) { image = "http://m.360buyimg.com/mobilecms/s800x800_" + image; pv.image = image; pv.image_from_url = image; } p.Values.Add(pv); //pr.value = v; //pr.name = mm[j].Groups[2].Value; //pr.number = new Random(Guid.NewGuid().GetHashCode()).Next(100, 1000); //pr.image = image; //pr.image_from_url = image; } } //去除sku.Props.Values为空的Props sku.Props = sku.Props.Where(o => o.Values.Count > 0).ToList(); sku.SkuNameExt = this.GetSkuNameEx(sku); //缓存html if (JingXiCollect.UseServerCache) { if (!canUse) //ServerTemp.Set(5, skuid.ToString(), html); IdFessionTaobao.ConcurrentQueueHtmlSaveServer.Enqueue(new Work.SaveServerParm() { SaveType = 5, ProuctId = skuid.ToString(), SaveHtml = html }); } return sku; } private string GetSkuNameEx(SkuInfo sku) { SkuInfo.SkuInfoDetail skuDetail = sku.SkuDetailList.Find(o => o.skuId == sku.SkuId); if (skuDetail == null) skuDetail = sku.SkuDetailList.Find(o => sku.SkuName.EndsWith(o.Prop1 + " " + o.Prop2 + " " + o.Prop3)); if (skuDetail == null) skuDetail = sku.SkuDetailList.Find(o => sku.SkuName.EndsWith(o.Prop1 + " " + o.Prop2)); Dictionary dicSkuName = new Dictionary(); //方法:根据skuDetail.Prop1模糊查找类别 foreach (var prop in sku.Props) { foreach (var v1 in prop.Values) { if (v1.name == skuDetail.Prop1 || v1.name == skuDetail.Prop2 || v1.name == skuDetail.Prop3) { dicSkuName.Add(prop.name, v1.name); break;//退出当前循环 } } } //另一种方式(备用):根据skuDetail.Prop1的索引,来获取:Prop1为sku.Props[0].name,Prop1为sku.Props[1].name。这种方式应该可行。暂时用第一种方法 List listSkuNameExt = new List(); foreach (var kv in dicSkuName) listSkuNameExt.Add(kv.Key + ":" + kv.Value); return string.Join(";", listSkuNameExt); } private KeyValueBase GetProvince_City(string address) { string strProvince = ""; string strCity = ""; string[] provice = "上海,北京,天津,重庆,黑龙江,辽宁,内蒙古,吉林,河北,河南,山西,山东,陕西,青海,宁夏,甘肃,新疆,西藏,四川,云南,贵州,广西,湖南,湖北,安徽,江苏,浙江,广东,福建,海南,台湾,香港,澳门".Split(','); string[] city = "上海,北京,天津,重庆,哈尔滨,沈阳,呼和浩特,长春,石家庄,郑州,太原,济南,西安,西宁,银川,兰州,乌鲁木齐,拉萨,成都,昆明,贵阳,南宁,长沙,武汉,合肥,南京,杭州,广州,福州,海口,台北,香港,澳门".Split(','); if (!string.IsNullOrEmpty(address)) { for (int i = 0; i < provice.Length; i++) { if (address.Contains(provice[i])) { strProvince = provice[i]; if (address.Length < 4) //直辖市 获取到的长度小于4 直辖市的省和市都是一样的 strCity = city[i]; else strCity = address.Replace(provice[i], ""); //现改成实际地址 break; } } } return new KeyValueBase(strCity, strProvince); } private List GetSpecification(long skuid) { #region // https://wq.jd.com/commodity/itembranch/getspecification?callback=commParamCallBackA&skuid=68021431223&t=0.3812012434945995 // commParamCallBackA({ // "errcode":"0", // "msg":"", // "data":{ "productSkuId":68021431223,"wReadMe":"","propGroups":[{"groupName":"主体","atts":[{"attName":"充电时间","categoryGroupAttId":"109107","attRemark":"","vals":["60-120分钟"],"sort":6}],"sort":1}]} //}) #endregion List list = new List(); //list.Add(new KeyValueBase("商品编号", skuid.ToString())); string url = "https://wq.jd.com/commodity/itembranch/getspecification?callback=commParamCallBackA&skuid=" + skuid; string html = AllBase.GetHtml.GetUtf8(url, AllBase.BaseClass.ChromeUserAgent); var atts = BaseRegex.GetMatchRegex(ref html, "\\{\\\"attName\\\".*?\\}"); foreach (Match m in atts) { string att = m.Value; string attName = BaseRegex.GetStringJson(ref att, "attName"); string vals = BaseRegex.GetMatchRegexString(ref att, "\"vals\":\\[\"(.+?)\"\\]"); list.Add(new KeyValueBase(attName, vals)); } return list; } private List GetDetailImageList(long skuid, string description) { #region // // { "content":"



","plus":false,"isMobileDesc":true,"msg":"","success":"1"} #endregion List list = new List(); string url = "https://wqsitem.jd.com/detail/" + skuid + "_" + description + "_normal.html"; string html = AllBase.GetHtml.GetUtf8(url, AllBase.BaseClass.ChromeUserAgent); html = AllBase.BaseRegex.Relpace(html, "
  • [\\w\\W]*
  • ", "");//过滤掉推荐的商品 //详情图-格式1 Dictionary> dic = new Dictionary>(); MatchCollection atts1 = BaseRegex.GetMatchRegex(ref html, "image:url\\((.+?)\\)"); MatchCollection atts = atts1; if (atts.Count == 0) { //详情图-格式2 MatchCollection atts2 = BaseRegex.GetMatchRegex(ref html, "src=[\"|'](.+?)[\"|']"); if (atts2.Count > atts.Count) atts = atts2; } if (atts.Count == 0) { //详情图-格式2 MatchCollection atts2 = BaseRegex.GetMatchRegex(ref html, "src=[\\\\\"|'](.+?)[\\\\\"|']"); if (atts2.Count > atts.Count) atts = atts2; } foreach (Match m in atts) { list.Add(m.Groups[1].Value.Trim('\'').Trim('"').Replace("http://img", "//img")); } return list; } /// /// 获取拼团的销量 /// /// /// private decimal GetPinTuanCount(long skuid) { string url = "https://wq.jd.com/pingou_api/GetBatTuanNum?callback=pgSearchNumCbB&skuids=" + skuid; string responseString = AllBase.GetHtml.GetUtf8(url, AllBase.BaseClass.ChromeUserAgent); decimal saleNum = 0; decimal.TryParse(AllBase.BaseRegex.GetStringJson(ref responseString, "tuancount"), out saleNum); return saleNum; } /// /// 获取单购的销量 /// /// /// private decimal GetGoodCount(long skuid) { string url = "https://wq.jd.com/commodity/comment/getcommentlist?callback=skuJDEvalA&version=v2&sceneval=2&score=0&sku=" + skuid + "&sorttype=5"; string refere = "https://item.m.jd.com/product/2490601.html?sku=" + skuid; string html = Work.GetPostTaobaoHtml.GetUrl(url, refere, false, ""); decimal saleNum = 0; decimal.TryParse(AllBase.BaseRegex.GetStringJson(ref html, "GoodCount"), out saleNum); return saleNum; } private class SkuInfo { /// /// 商品编号 /// public long SkuId; /// /// 商品名称 /// public string SkuName; /// /// 简短的商品名称,不带SKU标题 /// public string PName; /// /// 商品名称扩展,格式为:颜色:黑色;尺寸:20寸 /// 用途:拼多多上货用,为了迎合平多多现有的代码风格,不然要写很多代码; /// 填写该字段,拼多多上传代码风格就不需要改变 /// public string SkuNameExt; /// /// 主图第一张轮播图 /// public string Image; /// /// 品牌ID /// public string BrandId; /// /// 品牌 /// public string BrandName; /// /// 轮播图 /// public List ImageList = new List(); /// /// Sku明细 /// public List SkuDetailList = new List(); /// /// 拼购价格 /// public decimal PinGouPrice; /// /// 原价 /// public decimal BeforePrice; /// /// 售价:如果是拼购的,则是拼购价格;如果没有拼购,则是原价 /// public decimal SellPrice; /// /// 库存状态ID /// public int StockState; /// /// 库存状态名称 /// public string StockStateName; /// /// 运费 /// public decimal ExpressPrice; /// /// 店铺ID /// public long ShopId; /// /// 店铺名称 /// public string ShopName; /// /// 发货人 /// public string Deliver; /// /// 发货地址 /// public string DeliverAddress; /// /// 主视频ID /// public string MainVideoId; /// /// 销量 /// public decimal SaleNum; /// /// 省份 /// public string Province; /// /// 城市 /// public string City; /// /// 类目集合 /// public List Categorys = new List(); /// /// 详情属性集合 /// public List Prop = new List(); /// /// Sku属性集合 /// public List Props = new List(); /// /// 详情图集合 /// public List DetailImageList = new List(); /// /// 详情图集合的html /// public string DetailImageListHTML = ""; /// /// 库存数量 /// public int StockNumber; /// /// 支持7天无理由退货(使用后不支持) /// public string PromiseMark; /// /// 发货时间 /// //public string LogisticsTime; /// /// 采集的结果,空值代表OK /// public string msg = ""; public class SkuInfoDetail { public long skuId; public string Prop1 = ""; public string Prop2 = ""; public string Prop3 = ""; } } public enum GoodsStatusEnum { /// /// 无货 /// NotExist, /// /// 有货 /// Exist } } }