old_flsystem/应用/TBAppraisalTools/TbAnalysis.cs

527 lines
29 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Api.Framework.Tools;
using Api.Framework.Utils;
using CsharpHttpHelper;
using Newtonsoft.Json;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using TBAppraisalTools.Entitys;
namespace TBAppraisalTools
{
/// <summary>
/// 淘宝解析类
/// </summary>
public class TbAnalysis
{
/// <summary>
/// 获得淘宝的基础信息
/// </summary>
/// <param name="itemId">宝贝id</param>
/// <param name="cookies">淘宝的cookies</param>
public TbBaseInfo FindTbBaseInfo(string itemId)
{
// 目标: 店铺名称,店铺头像,标题,主图,价格,月销 优惠券金额,有效期 - 自定义
try
{
var html = "";
//var item = TbTools.GetH5Result("mtop.taobao.detail.getdetail", new { itemNumId = itemId, exParams = new { id = itemId }, detail_v = "3.1.1", ttid = "2018@taobao_iphone_9.9.9", utdid = "123123123123123" }, out html);
var item = TbTools.GetH5Result("mtop.taobao.detail.getdetail", new { itemNumId = itemId, exParams = new { id = itemId }, ttid = "2016@taobao_h5_2.0.0", isSec = "0", ecode = "0", AntiFlood = "true", AntiCreep = "true", H5Request = "true", type = "jsonp", dataType = "jsonp" }, out html);
var _item = item["item"] as Dictionary<string, object>;
var sellerId = string.Empty;
//这里可以通过图片的地址获取店铺的id
if (_item.ContainsKey("images"))
{
var images = _item["images"] as ArrayList;
if (images != null && images.Count != 0)
{
var reg = Regex.Match(images[0].ToString(), @"http://img.alicdn.com/imgextra/i\d/(?<店铺Id>\d+)/");
if (reg.Success)
sellerId = reg.Groups["店铺Id"].Value;
}
}
var price = string.Empty;//价格
var sellCount = string.Empty;
var apiStack = item["apiStack"] as ArrayList;
if (apiStack != null && apiStack.Count != 0)
{
var _apiStack = apiStack[0] as Dictionary<string, object>;
if (_apiStack.ContainsKey("value"))
{
var valueJsonStr = _apiStack["value"].ToString();
var valueJson = HttpExtend.JsonToDictionary(valueJsonStr);
#region sellCount
var itemTag = valueJson["item"] as Dictionary<string, object>;
if (itemTag.ContainsKey("sellCount"))
sellCount = itemTag["sellCount"].ToString();
#endregion
#region price
var priceTag = valueJson["price"] as Dictionary<string, object>;
if (priceTag.ContainsKey("price"))
{
var priceSub = priceTag["price"] as Dictionary<string, object>;
if (priceSub.ContainsKey("priceText"))
price = priceSub["priceText"].ToString();
}
if (string.IsNullOrEmpty(price) && priceTag.ContainsKey("transmitPrice"))
{
var transmitPrice = priceTag["transmitPrice"] as Dictionary<string, object>;
if (transmitPrice.ContainsKey("priceText"))
price = transmitPrice["priceText"].ToString();
}
if (!string.IsNullOrEmpty(price) && price.Contains("-")) //TODO 这里可能还存在带问号的价格,目前不清楚是什么情况,先空着
price = price.Split('-')[0];
#endregion
}
}
var _seller = item["seller"] as Dictionary<string, object>;
//店铺名称
var shopName = _seller["shopName"].ToString();
//店铺图片
string shopIcon = _seller["shopIcon"].ToString();
shopIcon = string.IsNullOrEmpty(shopIcon) ? "https://ss2.bdstatic.com/8_V1bjqh_Q23odCf/pacific/1659832877.jpg" : shopIcon.StartsWith("http") ? _seller["shopIcon"].ToString() : "http:" + _seller["shopIcon"].ToString();
if (string.IsNullOrEmpty(shopIcon) || shopName == "天猫超市")
shopIcon = "https://ss2.bdstatic.com/8_V1bjqh_Q23odCf/pacific/1659832877.jpg";
var userId = _seller["userId"].ToString();
//主图图片
var item_image = string.Empty;
if (_item.ContainsKey("images"))
item_image = (_item["images"] as ArrayList)[0].ToString();
//商品标题
var item_title = _item["title"].ToString();
return new TbBaseInfo() { ItemId = itemId, ItemImage = item_image, ItemTitle = item_title, Price = price, SellCount = sellCount, ShopIcon = shopIcon, ShopName = shopName, UserId = userId, SellerId = sellerId };
}
catch (Exception ex)
{
return null;
}
}
private Random ra = new Random();
/// <summary>
/// 生成优惠券图片
/// </summary>
/// <param name="tb">宝贝的信息</param>
/// <returns>返回生成后优惠券的路径,异常直接报错</returns>
public string GenerateCouponImage(TbBaseInfo tb)
{
try
{
if (File.Exists(TbTools.TBCONFIGJSON))//存在优惠券模板的情况
{
var objDic = JsonConvert.DeserializeObject<Dictionary<string, TbConfig>>(File.ReadAllText(TbTools.TBCONFIGJSON));
if (objDic != null)
{
var panel = objDic.FirstOrDefault(f => f.Key.Contains("panel"));
if (!default(KeyValuePair<string, object>).Equals(panel))
{
TbConfig tbConfig = objDic[panel.Key] as TbConfig;
if (!File.Exists(TbTools.BACKICO)) throw new Exception("不存在优惠券背景图");
var backImage = Tools.RefreshFileAddress(TbTools.BACKICO, TbTools.BASEPATH + @"\", Util.MapPath(TbTools.BASEPATH));
using (var backIco = new Bitmap(Image.FromFile(backImage), tbConfig.C_Size))
{
using (Graphics g = Graphics.FromImage(backIco))
{
#region discounts
var srcPrice = float.Parse(tb.Price);
var rates = Class1.Config.CouponDenomination.Split('-');
float min = 0.3f;//默认最小比例
float max = 0.6f;//默认最大比例
if (rates.Length == 2)
{
min = float.Parse(rates[0]) / 100f;//最小比例
max = float.Parse(rates[1]) / 100f;//最大比例
}
var discounts = (ra.Next(int.Parse(Math.Ceiling(srcPrice * min).ToString()), int.Parse(Math.Ceiling(srcPrice * max).ToString())));
//默认选中取整 时 - 商品现价要是小于10的时候将不会取整其他的取十的倍数
if (Class1.Config.IsRounding == Api.Framework.Enums.SwitchType.)
{
if (discounts > 10 && discounts < srcPrice)
{
double xx = discounts / 10;
discounts = int.Parse((Math.Round(xx) * 10).ToString());
}
}
#endregion
foreach (KeyValuePair<string, TbConfig> item in objDic)
{
var temp = item.Value;
if (item.Key.Contains("label"))
{
var validityBegin = string.Empty;//优惠券有效期开始日期
var validityEnd = string.Empty;//优惠券有效期结局日期
#region
if (temp.T_Text.Contains("#开始时间") || temp.T_Text.Contains("#结束时间"))
{
var tempDate = DateTime.Now.AddDays(Class1.Config.ManufacturePlansAddDay);
validityBegin = tempDate.ToString("yyyy.MM.dd");
validityEnd = tempDate.AddDays(Class1.Config.ExpirationDate).ToString("yyyy.MM.dd");
}
#endregion
var txt = temp.T_Text
.Replace("#店铺名称", tb.ShopName)
.Replace("#商品标题", tb.ItemTitle)
.Replace("#商品现价", tb.Price)
.Replace("#月销售量", tb.SellCount)
.Replace("#优惠券价", discounts.ToString())
.Replace("#券后特价", (float.Parse(tb.Price) - discounts).ToString())
.Replace("#开始时间", validityBegin)
.Replace("#结束时间", validityEnd);
SizeF crSize = new SizeF();
crSize = g.MeasureString(txt, temp.T_Font);
txt = Tools.RefreshTextFormat(tbConfig.C_Size.Width, temp.C_Point.X, txt, crSize.Width);
g.DrawString(txt, temp.T_Font, new SolidBrush(temp.T_ForeColor), temp.C_Point);
}
else if (item.Key.Contains("picbox"))
{
var tagDic = CsharpHttpHelper.HttpExtend.JsonToDictionary(temp.C_Tag.ToString());
var imageInfo = new ImageInfo() { ImagePath = tagDic["ImagePath"].ToString(), Shape = tagDic["Shape"].ToString() == "false" ? false : true, Varible = tagDic["Varible"].ToString() };
Bitmap bitmap = null;
if (imageInfo.Varible == "#店铺头像" || imageInfo.Varible == "#商品主图")
{
var cacheFile = TbTools.RandomFile();
Tools.DownloadImage(imageInfo.Varible == "#商品主图" ? tb.ItemImage : tb.ShopIcon, cacheFile);
bitmap = new Bitmap(Tools.ReadImageFile(cacheFile), temp.C_Size);
}
else if (imageInfo.Varible == "#其他图片")
{
var otherImage = Tools.RefreshFileAddress(imageInfo.ImagePath, @"评价工具\其他图片\", TbTools.OTHERSICOPATH);
bitmap = Tools.ReadImageFile(otherImage);
}
if (bitmap != null)
{
g.DrawImage(bitmap, temp.C_Point);
bitmap.Dispose();
bitmap = null;
}
}
}
}
var url = TbTools.RandomFile();
backIco.Save(url);
return url;
}
}
}
}
else
throw new Exception("未找到优惠券模板配置文件");
}
catch (Exception ex)
{
throw ex;
}
return string.Empty;
}
/// <summary>
/// 通过宝贝id获取宝贝评价标签集合
/// </summary>
/// <param name="itemId">宝贝id</param>
/// <returns>返回标签集合</returns>
public List<TagCloud> FindTagsByItemId(string itemId)
{
try
{
var tags = TbTools.FindTagsByItemId(itemId);
if (tags != null) tags = tags.Where(f => f.posi).ToList();
return tags;
}
catch (Exception ex)
{
throw ex;
}
}
/// <summary>
/// 获取PC端的评语信息
/// </summary>
/// <param name="itemId">宝贝Id</param>
/// <param name="sellerId">店铺Id</param>
/// <param name="analyticPageNum">分析多少页</param>
/// <param name="tagid">标签的id</param>
/// <returns></returns>
public List<Comment> FindPcCommentInfos(string itemId, string sellerId, int analyticPageNum, int tagid = 0)
{
try
{
try
{
var comments = new List<Comment>();
for (int i = 1; i <= analyticPageNum; i++)
{
//int error = 0;
// Next:
string url = string.Format("https://rate.tmall.com/list_detail_rate.htm?itemId={0}&sellerId={1}&order=3&currentPage={2}&append=0&content=1&posi=1&picture=&callback=jsonp443&tagId={3}", itemId, sellerId, analyticPageNum, tagid);
//var cookies = Tools.ReadTBCookies();
HttpHelper http = new HttpHelper();
var item = http.GetItem(url);
item.Cookie = TbTools.RandomTbCookies();
item.Allowautoredirect = true;
item.UserAgent = @"Mozilla/4.0 (compatible; MSIE 9.0; Windows NT6.1)";
item.ContentType = @"application/x-www-form-urlencoded";
var result = http.GetHtml(item);
var html = result.Html.Trim();
//TbCookies = result.Cookie;//这个就不保存了,因为写了淘宝心跳
if (!html.StartsWith("jsonp443")) throw new Exception("评语解析不出:" + html);
html = html.Replace("jsonp443(", "").Replace(")", "");
var json = HttpExtend.JsonToDictionary(html) as Dictionary<string, object>;
if (json != null && json.ContainsKey("rgv587_flag"))//登录过期
throw new Exception("淘宝已经掉线,请重新登录~!");//这里可能会是频率显示(歇息一下,喝口水什么的)
if (json == null || !json.ContainsKey("rateDetail")) throw new Exception("未获得评价数据:" + html);
json = json["rateDetail"] as Dictionary<string, object>;
if (!json.ContainsKey("rateList")) throw new Exception("该宝贝没有评论数据");
var list = json["rateList"] as ArrayList;
foreach (Dictionary<string, object> obj in list)
{
var pics = obj["pics"] as ArrayList;
var comment = new Comment() { position = obj["position"].ToString(), rateContent = obj["rateContent"].ToString() };
if (pics != null)
{
foreach (var t in pics)
{
comment.pics.Add("http:" + t);
}
}
comments.Add(comment);
}
if (json.ContainsKey("paginator"))//获取评论区的页数
{
var paginator = json["paginator"] as Dictionary<string, object>;
var lastPage = int.Parse(paginator["lastPage"].ToString());//总页数
var page = int.Parse(paginator["page"].ToString());//当前页数
if (lastPage <= page) break;
}
}
return comments;
}
catch (Exception ex)
{
throw ex;
}
//return new List<Comment>();
}
catch (Exception ex)
{
throw ex;
}
}
/// <summary>
/// 获取移动端的评语信息
/// </summary>
/// <param name="itemId">宝贝Id</param>
/// <param name="sellerId">店铺Id</param>
/// <param name="analyticPageNum">分析多少页</param>
/// <param name="tagid">标签Id</param>
/// <returns></returns>
public List<Comment> FindWebappCommentInfos(string itemId, int analyticPageNum)
{
try
{
List<Comment> commentList = new List<Comment>();
TaskTool tasks = new TaskTool();
for (int i = 1; i <= analyticPageNum; i++)
{
var _i = i;
tasks.AddTask(delegate
{
try
{
//获取评价json数据
var json = string.Empty;
var _url = @"https://rate.taobao.com/feedRateList.htm?auctionNumId=" + itemId + "&userNumId=" + new Random(Guid.NewGuid().GetHashCode()).Next(100000, 999999).ToString() + new Random(Guid.NewGuid().GetHashCode()).Next(10000, 99999) + "&currentPageNum=" + _i + "&pageSize=20&rateType=&orderType=sort_weight&attribute=&sku=&hasSku=false&folded=0&callback=jsonp_tbcrate_reviews_list";
HttpHelper http = new HttpHelper();
var temp = http.GetItem(_url);
temp.Cookie = TbTools.RandomTbCookies();
temp.SetProxyipCDN();
temp.Allowautoredirect = true;
temp.UserAgent = @"Mozilla/4.0 (compatible; MSIE 9.0; Windows NT6.1)";
temp.ContentType = @"application/x-www-form-urlencoded";
var rst = http.GetHtml(temp);
//if (!string.IsNullOrEmpty(rst.Cookie)) rst.UpdateCookies(temp.Cookie);//更新cookies
json = rst.Html.Replace("jsonp_tbcrate_reviews_list(", "").Trim();
json = json.Substring(0, json.Length - 1);
//StringBuilder strb = new StringBuilder();
//StringBuilder strbPic = new StringBuilder();
var obj = HttpExtend.JsonToDictionary(json);
#region
var maxPageObj = obj["maxPage"];
var maxPage = -1;
if (maxPageObj != null)
maxPage = int.Parse(maxPageObj.ToString());
#endregion
#region
var comments = obj["comments"] as ArrayList;
if (comments != null && comments.Count != 0)
{
foreach (var _item in comments)
{
var pj = new Comment();
var item = _item as Dictionary<string, object>;
var photos = item["photos"] as ArrayList;
if (photos != null && photos.Count != 0)
{
foreach (var _pic in photos)
{
var pic = _pic as Dictionary<string, object>;
var url = pic["url"].ToString();//图片
pj.pics.Add("http:" + url);
}
}
var content = item["content"].ToString();//初评语
if (content != "此用户没有填写评价。")
pj.rateContent = content;
var appendList = item["appendList"] as ArrayList;//追评数量
if (appendList != null && appendList.Count != 0)
{
foreach (var _appendItem in appendList)//追评部分
{
var appendItem = _appendItem as Dictionary<string, object>;
var appendPhotos = appendItem["photos"] as ArrayList;
if (appendPhotos != null && appendPhotos.Count != 0)
{
foreach (var _appendPic in appendPhotos)
{
var appendPic = _appendPic as Dictionary<string, object>;
var appendUrl = appendPic["url"].ToString();//追加图片
pj.pics.Add("http:" + appendUrl);
}
}
var appendContent = appendItem["content"].ToString();//追评语
if (content != "此用户没有填写评价。")
pj.rateContent += appendContent;
}
}
if (!string.IsNullOrEmpty(pj.rateContent)) commentList.Add(pj);
}
}
#endregion
}
catch { }
});
}
tasks.Start(10, null);
return commentList;
}
catch (Exception ex)
{
throw ex;
}
}
/// <summary>
/// 将图片集合转换成Gif图片
/// </summary>
/// <param name="pics">图片集合</param>
/// <param name="secondImage">最后一针图片(底图)</param>
/// <param name="path"></param>
/// <param name="time">图片之间的间隔时间</param>
/// <param name="repeat">是否重复</param>
public void FindGifsBySrcPic(List<string> pics, string secondImage, string path, string itemId, int time = 0, bool repeat = false)
{
try
{
if (pics != null && pics.Count != 0) //判断是否图片集合为空
{
//if (Directory.Exists(path)) //检测是否存在日期部分的目录
//{
// if (Directory.Exists($"{path}\\{itemId}")) //检测当天解析的宝贝一样时,删除之前解析的所有内容
// Tools.DelectDir(path);
//}
//else
// throw new Exception("解析以后保存路径不存在,请先设置保存路径");
TaskTool tasks = new TaskTool(); //定义线程池
foreach (var pic in pics) //循环要遍历的图片
{
tasks.AddTask(delegate () //添加线程任务
{
try
{
var secondImg = Tools.ReadImageFile(secondImage); //获取优惠券bitmap
var bitmap = Tools.ZoomPicture(Image.FromFile(pic), secondImg.Width, secondImg.Height);//评价图压缩成和优惠券图大小一致
Graphics g = null;
if (File.Exists(TbTools.BUTTONICO)) //是否有按钮图标
{
g = Graphics.FromImage(bitmap); //创建以底图为基础的画板
var bitmapLogo = Tools.ReadImageFile(TbTools.BUTTONICO); //按钮图片bitmap
int size = 200; //按钮大小
float rate = 2.00f; //比例
bitmapLogo = new Bitmap(bitmapLogo, new Size(size, size)); //固定按钮的大小
var point = new PointF(secondImg.Width / rate - size / rate, secondImg.Height / rate - size / rate); //按钮的坐标
g.DrawImage(bitmapLogo, point); //将按钮画在底图中
}
//000000000000
var saveImgPath = TbTools.RandomFile(); //带随机名字的缓存地址(临时图片)
bitmap.Save(saveImgPath); //将评价图保存只缓存
if (g != null) //如果增加了按钮,则将画板释放
g.Dispose();
bitmap.Dispose(); //释放
if (Class1.Config.BondCommentPic == Api.Framework.Enums.SwitchType.)
{
var gifFile = Tools.PngsToGif(new string[] { saveImgPath, secondImage }, Util.MapFile(Guid.NewGuid().ToString() + ".png", path), time, repeat); //将处理好的图片保存在宝贝路径中
if (!string.IsNullOrEmpty(gifFile))
{
if (File.Exists(saveImgPath))
try
{
File.Delete(saveImgPath); //删除临时图片
}
catch (Exception ex)
{ }
}
}
else
{
}
}
catch (Exception ex)
{
}
});
}
tasks.Start(8, null); //执行线程池
}
}
catch (Exception ex)
{
throw ex;
}
}
}
}