/// <summary> /// 将该产品的SKU数据导出为EXCEL /// </summary> /// <param name="productUrl"></param> public List<ProductColor> ExportProductColorForExcel(string productUrl) { if (productUrl.IsNullOrEmpty()) throw new Exception(Resource.Exception_NotFoundAuthorizedCode.StringFormat(new StackTrace())); string goodsSn = GetGoodsSn(productUrl); _log.LogInfo(Resource.Log_ExportProductColorForExceling.StringFormat(goodsSn)); //const string sheetName = Resource.SysConfig_Sku; var excel = CreateExcelForBanggoSku(sheetName); DataTable dt = excel.ReadTable(sheetName); var request = new RequestModel {GoodsSn = goodsSn, Referer = productUrl}; var lstProductColor = GetProductColorByOnline(request); DataRow drNew = dt.NewRow(); drNew["产品地址"] = productUrl; drNew["款号"] = goodsSn; drNew["售价"] = 0; CheckStock(lstProductColor, drNew); excel.AddNewRow(drNew); _log.LogInfo(Resource.Log_ExportProductColorForExcelSuccess.StringFormat(goodsSn)); return lstProductColor; }
//读取或构造单个产品的基础信息 /// <summary> /// 读取或构造单个产品的基础信息。 /// 包括:标题、价格、销量、产品描述 /// </summary> /// <param name="product">产品</param> /// <param name="requestModel">请求模型</param> private void GetProductBaseInfo(BanggoProduct product, RequestModel requestModel) { #region 得到banggo数据 product.ThrowIfNull(Resource.ExceptionTemplate_MethedParameterIsNullorEmpty.StringFormat( new StackTrace())); requestModel.ThrowIfNull(Resource.ExceptionTemplate_MethedParameterIsNullorEmpty.StringFormat( new StackTrace())); var doc = SysUtils.GetHtmlDocumentByHttpGet(requestModel.Referer,Encoding.UTF8); #endregion #region 获得品牌 HtmlNode selectNodesForProductBrandCode = doc.DocumentNode.SelectSingleNode(Resource.SysConfig_GetBanggoProductBrandCodeXPath); if (selectNodesForProductBrandCode == null) { FileHelper.WriteFileLog("邦购没有的产品.txt", requestModel.GoodsSn); } selectNodesForProductBrandCode.ThrowIfNull(Resource.Exception_XPathGetDataError.StringFormat( new StackTrace())); product.Brand = selectNodesForProductBrandCode.InnerText; #endregion #region 获取产品详细界面的类别 HtmlNode selectNodesForProductCategory = doc.DocumentNode.SelectSingleNode(Resource.SysConfig_GetBanggoProductCategoryXPath); selectNodesForProductCategory.ThrowIfNull(Resource.Exception_XPathGetDataError.StringFormat( new StackTrace())); product.Category = selectNodesForProductCategory.InnerText; #endregion #region 得到banggo的父目录,如 T恤 HtmlNode selectNodeForProductParentCatalog = doc.DocumentNode.SelectSingleNode(Resource.SysConfig_GetBanggoProductParentCatalogXPath); selectNodeForProductParentCatalog.ThrowIfNull(Resource.Exception_XPathGetDataError.StringFormat( new StackTrace())); product.ParentCatalog = selectNodeForProductParentCatalog.InnerHtml; #endregion #region 获得产品目录 HtmlNode selectNodesForProductCatalog = doc.DocumentNode.SelectSingleNode(Resource.SysConfig_GetBanggoProductCatalogXPath); // selectNodesForProductCatalog.ThrowIfNull(Resource.Exception_XPathGetDataError.StringFormat( // new StackTrace())); product.Catalog = selectNodesForProductCatalog != null ? selectNodesForProductCatalog.InnerText : ""; #endregion #region 得到产品描述 //修改获取的HTML img 的SRC URL HtmlNodeCollection imgNodes = doc.DocumentNode.SelectNodes(Resource.SysConfig_GetGoodsModeImgGreyXPath); sbDesc.Clear(); sbDesc.AppendLine(SysConst.PrefixGoodsDesc); sbDesc.AppendLine( "款号:{1} -> Banggo 产品地址:<a href=\"{0}\" target=\"_blank\" title=\"{0}\">{0}</a> <br/>".StringFormat( requestModel.Referer,product.GoodsSn)); #region 这是用html的方式,现在淘宝不支持外链接图片,所以只有用截图的方法 if (imgNodes != null) { sbDesc.AppendLine(GetProductDesc(requestModel, imgNodes, doc, Resource.SysConfig_GoodsDescId)); } else { #region 处理请求HTML 没有grey.gif的情况,以及产品描述节点ID不为Goods_Mode的情况 //有可能是没有grey.gif文件,检查是否有描述结点。如果有,直接返回 var desNode = doc.GetElementbyId(Resource.SysConfig_GoodsDescId); if (desNode != null) { sbDesc.AppendLine(desNode.OuterHtml); } else //说明是该描述id为productinfo_div { //检查是否有grey.gif文件 imgNodes = doc.DocumentNode.SelectNodes( Resource.SysConfig_GetProductInfoImgGreyXPath); if (imgNodes != null) { sbDesc.AppendLine(GetProductDesc(requestModel, imgNodes, doc, Resource.SysConfig_ProductInfoId)); } else { //检查是否有productinfo_div结点 var descNode = doc.GetElementbyId(Resource.SysConfig_ProductInfoId); if (descNode != null) { sbDesc.AppendLine(descNode.OuterHtml); } else { sbDesc.AppendLine("详情到:" + requestModel.Referer); } } } #endregion } #endregion product.Desc = ModifyGoodsDetailsCss(sbDesc.ToString()); //todo截图没有实现 /* var lstFile = new List<FileItem>(); using (var bitmap = CaputureHtmlElement.CaptureBanggo(requestModel.Referer)) { var fileItem = new FileItem("{0}Detail.jpg".StringFormat(product.GoodsSn),ImageHelper.SetBitmapToBytes(bitmap,System.Drawing.Imaging.ImageFormat.Jpeg)); lstFile.Add(fileItem); } product.GoodsDetailPic = lstFile;*/ #endregion }
//读取Desc数据,因为有些产品描述的Id是productinfo_div private static string GetProductDesc(RequestModel requestModel, HtmlNodeCollection imgNodes, HtmlDocument doc, string detailId) { string desc; foreach (HtmlNode imgNode in imgNodes) { imgNode.SetAttributeValue("src", imgNode.GetAttributeValue("original", "")); } var desNode = doc.GetElementbyId(detailId); if (desNode != null) { desc = desNode.OuterHtml; } else { desc = "详情到:" + requestModel.Referer; } return desc; }
//得到Price/getGoodsPrice(获得该商品的价格、颜色)的响应内容 private static string GetGoodsPriceAndColorContent(RequestModel requestModel) { var cookieJar = new CookieContainer(); string url = Resource.SysConfig_GetGoodsPriceByBanggoUrl.StringFormat(DateTime.Now.Ticks, requestModel.GoodsSn); var restClient = new RestClient(url) {CookieContainer = cookieJar}; var request = new RestRequest(Method.GET); request.AddHeader("Host", "act.banggo.com"); request.AddHeader("Accept", "*/*"); request.AddHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31"); request.AddHeader("Referer", requestModel.Referer); request.AddHeader("Accept-Encoding", "gzip,deflate,sdch"); request.AddHeader("Accept-Language", "zh-CN,zh;q=0.8"); request.AddHeader("Accept-Charset", "GBK,utf-8;q=0.7,*;q=0.3"); IRestResponse response = restClient.Execute(request); if (response.ErrorException != null) throw response.ErrorException; string result = ReplaceBracket(response.Content); return result; }
/// <summary> /// 得到SKU基本信息不包括,颜色和尺码, 主要用于手动发布产品功能 /// </summary> /// <param name="product"></param> /// <param name="requestModel"></param> public HtmlDocument GetProductSkuBase(BanggoProduct product, RequestModel requestModel) { string result = GetGoodsPriceAndColorContent(requestModel); JObject jObj = JObject.Parse(result); var data = jObj.SelectToken("data").Value<string>(); var doc = new HtmlDocument(); doc.LoadHtml(data); product.ThumbUrl = jObj.SelectToken("thumb_url").Value<string>(); GetPriceAndSalesVolume(product, doc); product.BSizeToTSize = GetBSizeToTSize(doc); return doc; }
//得到产品的颜色和大小数据,通过在线读取,该方法主要用于以自动无干预自动上产品 public List<ProductColor> GetProductColorByOnline(RequestModel requestModelbase, HtmlDocument doc) { BanggoRequestModel requestModel = new BanggoRequestModel(); Util.CopyModel(requestModelbase, requestModel); HtmlNode htmlNodeColorList = doc.GetElementbyId(Resource.SysConfig_ColorListId); if (htmlNodeColorList.IsNull()) return null; HtmlNodeCollection colors = htmlNodeColorList.SelectNodes("li/a"); if (colors.IsNull()) return null; var colorList = new List<ProductColor>(); foreach (HtmlNode colorNode in colors) { string colorInfo = colorNode.Attributes["onclick"].Value; ProductColor productColor = CreateProductColor(colorInfo); requestModel.ColorCode = productColor.ColorCode; productColor.SizeList = GetAvailableSize(requestModel); foreach (var size in productColor.SizeList) { productColor.AvlNumForColor += size.AvlNum; } colorList.Add(productColor); } return colorList; }
/// <summary> /// 得到可售商品Sku /// </summary> /// <param name="product">产品</param> /// <param name="requestModel">请求模型</param> public void GetProductSku(Product product, RequestModel requestModel) { BanggoProduct banggoProduct; bool isError = false; try//如果该对象以前是父类,那么此时就直接强制转换,如果不是都重新new一个子类,然后进行赋值 { banggoProduct = (BanggoProduct) product; } catch (Exception) { isError = true; banggoProduct = new BanggoProduct(); Util.CopyModel(product, banggoProduct); } var doc = GetProductSkuBase(banggoProduct, requestModel); banggoProduct.ColorList = GetProductColorByOnline(requestModel, doc); if (isError) //如果是new的一个新对象,那么,就要把在GetProductSkuBase,GetProductColorByOnline中获取到的值,赋给product对象 { Util.CopyModel(banggoProduct,product); } }
/// <summary> /// 得到产品的颜色和大小数据,通过在线读取 /// 该方法主要用于为手动干预价格,提供SKU数据 /// </summary> /// <param name="requestModel">Referer\GoodsSn 必须传入</param> /// <returns></returns> public List<ProductColor> GetProductColorByOnline(RequestModel requestModel) { var doc = GetGoodsDetialElementData(requestModel); return GetProductColorByOnline(requestModel, doc); }
/// <summary> /// 得到单个产品信息 /// </summary> /// <param name="requestModel"></param> /// <returns></returns> public Product GetGoodsInfo(RequestModel requestModel) { var product = new BanggoProduct {GoodsSn = requestModel.GoodsSn}; GetProductBaseInfo(product, requestModel); GetProductSku(product, requestModel); return product; }
//得到产品详细界面的Data元素数据 public HtmlDocument GetGoodsDetialElementData(RequestModel requestModel) { //得到产品详情界面数据 string result = GetGoodsPriceAndColorContent(requestModel); JObject jObj = JObject.Parse(result); var data = jObj.SelectToken("data").Value<string>(); var doc = new HtmlDocument(); doc.LoadHtml(data); return doc; }
/// <summary> /// 将多个产品的SKU数据导出为EXCEL /// </summary> /// <param name="productUrls"></param> public void ExportProductColorsForExcel(params string[] productUrls) { if (productUrls.IsNullOrEmpty()) throw new Exception(Resource.Exception_NotFoundAuthorizedCode.StringFormat(new StackTrace())); string sheetName = Resource.SysConfig_Sku; var excel = CreateExcelForBanggoSku(sheetName); DataTable dt = excel.ReadTable(sheetName); foreach (var productUrl in productUrls) { string goodsSn = GetGoodsSn(productUrl); var request = new RequestModel { GoodsSn = goodsSn, Referer = productUrl }; var lstProductColor = GetProductColorByOnline(request); DataRow drNew = dt.NewRow(); drNew["产品地址"] = productUrl; drNew["款号"] = goodsSn; drNew["售价"] = 0; CheckStock(lstProductColor, drNew); excel.AddNewRow(drNew); } }
//发布商品的主方法 private Item PublishGoodsMain(IRequest req, RequestModel requestModel) { try { Product product = req.GetGoodsInfo(requestModel); product.SetAddProperty(); if (product.ColorList.IsNullOrEmpty()) return null; req.SetCidAndSellerCids(product); return PublishGoodsAndUploadPic(product); } catch (Exception e) { _log.LogError("发布该产品失败,邦购没有该产品:{0}", e, requestModel.GoodsSn); return null; } }