415 lines
18 KiB
C#
415 lines
18 KiB
C#
|
using Api.Framework;
|
|||
|
using Api.Framework.Enums;
|
|||
|
using Api.Framework.Tools;
|
|||
|
using CsharpHttpHelper;
|
|||
|
using System;
|
|||
|
using System.Collections;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.IO;
|
|||
|
using System.Linq;
|
|||
|
using System.Text;
|
|||
|
using System.Text.RegularExpressions;
|
|||
|
using System.Threading;
|
|||
|
using System.Threading.Tasks;
|
|||
|
using System.Web;
|
|||
|
using TBAppraisalTools.Properties;
|
|||
|
|
|||
|
namespace TBAppraisalTools
|
|||
|
{
|
|||
|
public class TbTools
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
/// 基础路径
|
|||
|
/// </summary>
|
|||
|
public static string BASEPATH = @"File\评价工具缓存";
|
|||
|
/// <summary>
|
|||
|
/// 优惠模板的配置
|
|||
|
/// </summary>
|
|||
|
public static string TBCONFIGJSON = Util.MapFile("TBAppraisalTools.ConfigJson.txt", BASEPATH);
|
|||
|
/// <summary>
|
|||
|
/// 商品主图保存地址
|
|||
|
/// </summary>
|
|||
|
public static string ITEMICO = Util.MapFile("商品主图.png", BASEPATH);
|
|||
|
/// <summary>
|
|||
|
/// 店铺头像保存地址
|
|||
|
/// </summary>
|
|||
|
public static string SHOPICO = Util.MapFile("店铺头像.png", BASEPATH);
|
|||
|
/// <summary>
|
|||
|
/// 优惠券背景保存地址
|
|||
|
/// </summary>
|
|||
|
public static string BACKICO = Util.MapFile("优惠券背景.png", BASEPATH);
|
|||
|
/// <summary>
|
|||
|
/// 用户自定义诱导图保存地址
|
|||
|
/// </summary>
|
|||
|
public static string ABDUCTIONICO = Util.MapFile("诱导图.png", BASEPATH);
|
|||
|
/// <summary>
|
|||
|
/// 用户自定义按钮图片保存地址
|
|||
|
/// </summary>
|
|||
|
public static string BUTTONICO = Util.MapFile("按钮.png", BASEPATH);
|
|||
|
/// <summary>
|
|||
|
/// 其他图片保存路径
|
|||
|
/// </summary>
|
|||
|
public static string OTHERSICOPATH = Util.MapPath(BASEPATH + @"\其他图片");
|
|||
|
|
|||
|
public static string CACHEPATH = Util.MapPath(@"Cache\image");
|
|||
|
|
|||
|
public static string RandomFile()
|
|||
|
{
|
|||
|
return Util.MapFile(Guid.NewGuid().ToString() + ".png", @"Cache\image");
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 随机返回一个Cookies
|
|||
|
/// </summary>
|
|||
|
/// <returns></returns>
|
|||
|
public static string RandomTbCookies()
|
|||
|
{
|
|||
|
return "x5sec=7b22726174656d616e616765723b32223a223532646630323530396539363062626235633533306632383630376138666231435053657165414645496e6e3265324c6d71336275674561444445314f54557a4e5467784d7a51374d513d3d227d; cookie2=1deb2e55c9854743bc58dab7e9713758; _tb_token_=f1e53753884e3; t=0240c13f37355b4b835b319127b5af8c";
|
|||
|
//if (Class1.Config.TbLoginInfos != null)
|
|||
|
//{
|
|||
|
// var tbLoginInfo = Class1.Config.TbLoginInfos.Where(f => f.OnLine == SwitchType.开启).OrderBy(f => Guid.NewGuid()).Take(1).FirstOrDefault();
|
|||
|
// if (tbLoginInfo != null) return tbLoginInfo.Cookies;
|
|||
|
//}
|
|||
|
//return string.Empty;
|
|||
|
}
|
|||
|
|
|||
|
#region h5Top
|
|||
|
|
|||
|
private static string _cookies = string.Empty;
|
|||
|
|
|||
|
private static string Cookies
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
if (string.IsNullOrEmpty(_cookies))
|
|||
|
{
|
|||
|
HttpHelper http = new HttpHelper();
|
|||
|
string cookies = http.GetHtml(new HttpItem() { URL = "http://api.m.taobao.com/h5/mtop.alimama.union.hsf.coupon.get/1.0/?v=1.0&api=mtop.alimama.union.hsf.coupon.get&appKey=12574478&t=1521082116428&callback=mtopjsonp1&type=jsonp&sign=e102e09c3da2505790412f4b5904cfec&data=%7B%22e%22%3A%22kKwRS8jKFeIGQASttHIRqX4ccS%252BmEB0fPkvI%252B9vDGidk3qypIGt1zv02HjWWzK8QrVVJXxMdEXoJP%252FpVy45HN79fwBwwUiqlbZt%252F%252F9VQxkYKu2xm%252BXzUVW7PVn13QcLNcISolD8QJ4rvZt%252BicRrQwg%253D%253D%22%2C%22pid%22%3A%22mm_96747532_17602904_63786428%22%7D", Timeout = 5000, ReadWriteTimeout = 5000 }).Cookie;
|
|||
|
_cookies = HttpHelper.GetSmallCookie(cookies);
|
|||
|
}
|
|||
|
return _cookies;
|
|||
|
}
|
|||
|
set { _cookies = value; }
|
|||
|
}
|
|||
|
|
|||
|
const string appKey = "12574478";
|
|||
|
|
|||
|
public static Dictionary<string, object> GetH5Result(string api, object data, out string html, string version = "6.0")
|
|||
|
{
|
|||
|
bool next = false;
|
|||
|
Next:
|
|||
|
string time = ((DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000).ToString();
|
|||
|
string mh5Tk = HttpExtend.GetCookiesValue("_m_h5_tk", Cookies);
|
|||
|
mh5Tk = string.IsNullOrEmpty(mh5Tk) ? "f64aa152f943661f750e6212ebc98804_1481170439770" : mh5Tk;
|
|||
|
string json = (data.GetType() == typeof(string)) ? data.ToString() : HttpHelper.ObjectToJson(data).Replace("\\u0026", "&").Replace("_params", "param");
|
|||
|
string temp_ = mh5Tk + "&" + time + "&" + appKey + "&" + json;
|
|||
|
string sign = HttpExtend.GetMD5String(temp_);
|
|||
|
string send = HttpExtend.UrlEncode(json);
|
|||
|
string temp = string.Format("http://h5api.m.taobao.com/h5/{5}/{4}/?jsv=2.4.11&v={4}&api={5}&appKey={0}&t={1}&callback=mtopjsonp1&type=jsonp&sign={2}&data={3}", appKey, time, sign, send, version, api);
|
|||
|
html = M_GET_HTML(temp).Trim();
|
|||
|
if (html.Contains("令牌过期") || html.Contains("令牌为空") || html.Contains("失效"))
|
|||
|
{
|
|||
|
if (!next)
|
|||
|
{
|
|||
|
next = true;
|
|||
|
goto Next;
|
|||
|
}
|
|||
|
}
|
|||
|
if (html.Contains("挤爆"))
|
|||
|
{
|
|||
|
Dictionary<string, object> _json = HttpExtend.JsonToDictionary(html);
|
|||
|
|
|||
|
string _url = (_json["data"] as Dictionary<string, object>)["url"].ToString();
|
|||
|
next = false;
|
|||
|
goto Next;
|
|||
|
}
|
|||
|
|
|||
|
var reg = Regex.Match(html, @"^mtopjsonp1\((.*?)\)$", RegexOptions.IgnoreCase);
|
|||
|
if (reg.Success)
|
|||
|
{
|
|||
|
var dic = HttpExtend.JsonToDictionary(reg.Groups[1].Value);
|
|||
|
if (dic.ContainsKey("data") && html.Contains("SUCCESS::调用成功"))
|
|||
|
return dic["data"] as Dictionary<string, object>;
|
|||
|
throw new Exception(reg.Groups[1].Value);
|
|||
|
}
|
|||
|
throw new Exception(html);
|
|||
|
}
|
|||
|
|
|||
|
internal const string _key = "<RSAKeyValue><Modulus>wmUZgme6iOPOaMTZtPu5DKQ8Dph9fSgy6abFyQv25MD8xOMPBBo0wsLUOVt8r9sk+li11mIg1fs1HPJ75UmIle+w9xhIx/nsXWejuQhXlQV0VyJtzI+id8G+FcyYaog91MfPndJoO3m30fSjE/0KDLDmv1EeQcP24RAzeA29p7c=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
|
|||
|
internal const int _appid = 10004;
|
|||
|
internal const string _host = "https://cps.api.52cmg.cn";
|
|||
|
|
|||
|
private static string M_GET_HTML(string tempUrl)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
HttpItem item = new HttpItem()
|
|||
|
{
|
|||
|
URL = tempUrl,//URL 必需项
|
|||
|
Method = "get",//URL 可选项 默认为Get
|
|||
|
IsToLower = false,//得到的HTML代码是否转成小写 可选项默认转小写
|
|||
|
Cookie = Cookies + ";random=" + new Random().Next(),//字符串Cookie 可选项
|
|||
|
Referer = "http://m.taobao.com",//来源URL 可选项
|
|||
|
Timeout = 5000,//连接超时时间 可选项默认为100000
|
|||
|
ReadWriteTimeout = 5000,//写入Post数据超时时间 可选项默认为30000
|
|||
|
UserAgent = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)",//用户的浏览器类型,版本,操作系统 可选项有默认值
|
|||
|
ContentType = "text/html",//返回类型 可选项有默认值
|
|||
|
Allowautoredirect = false,//是否根据301跳转 可选项
|
|||
|
};
|
|||
|
HttpHelper http = new HttpHelper();
|
|||
|
int i = 0;
|
|||
|
Next:
|
|||
|
HttpResult result = http.GetHtml(item);
|
|||
|
string html = result.Html;
|
|||
|
if (Regex.IsMatch(html, Resources.KeyWords))
|
|||
|
{
|
|||
|
var r = item.SetProxyIP(http, new AuthEndpoint()
|
|||
|
{
|
|||
|
Host = _host + "/api/webtool.asmx/send_data",
|
|||
|
Appid = _appid,
|
|||
|
Enckey = _key,
|
|||
|
Method = "find_proxy"
|
|||
|
});
|
|||
|
i++;
|
|||
|
if (r && i < 3) goto Next;
|
|||
|
}
|
|||
|
if (!string.IsNullOrEmpty(result.Cookie))
|
|||
|
{
|
|||
|
Cookies = HttpExtend.UpdateCookies(Cookies, result.Cookie);
|
|||
|
}
|
|||
|
return html;
|
|||
|
}
|
|||
|
catch (Exception)
|
|||
|
{
|
|||
|
return string.Empty;
|
|||
|
}
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region GetXsign算法
|
|||
|
public string GetXsign(string api, object data, string v = "4.0")
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
var _data = HttpHelper.ObjectToJson(data);
|
|||
|
//string goodid = "576534346099";
|
|||
|
//var _data = HttpHelper.ObjectToJson(new
|
|||
|
//{
|
|||
|
// hasPic = "1",
|
|||
|
// pageNo = "1",
|
|||
|
// rateType = "2",
|
|||
|
// auctionNumId = goodid,
|
|||
|
// pageSize = "10"
|
|||
|
//});// UrlEncode().Replace("\\u0026", "&");
|
|||
|
var byte_data = Encoding.UTF8.GetBytes(_data);
|
|||
|
//var str = $"&xsid=&ttid=255200%40taobao_android_6.9.0&deviceId=AtDfW5xiq9pfKSGj8ZGohk11_7ho-iA4o_qrEZaVyYU1&lat=&lng=&features=";
|
|||
|
string str_md52 = HttpExtend.GetMD5String(_data).ToLower();
|
|||
|
Dictionary<string, object> obj = new Dictionary<string, object>();
|
|||
|
obj["api"] = api;
|
|||
|
obj["date"] = str_md52;
|
|||
|
obj["v"] = v;
|
|||
|
obj["x-lat"] = "39.916295";
|
|||
|
obj["x-lng"] = "116.410344";
|
|||
|
obj["x-utdid"] = "W8YPqceRx24DAFCBVtSNaUg8";
|
|||
|
obj["appkey"] = "21646297";
|
|||
|
obj["x-ttid"] = "600000@taobao_android_7.6.0";
|
|||
|
obj["x-devid"] = "AtDfW5xiq9pfKSGj8ZGohk11_7ho-iA4o_qrEZaVyYU1";
|
|||
|
obj["x-features"] = "27";
|
|||
|
obj["x-t"] = HttpExtend.GetTimeStamp();
|
|||
|
var _app = SendData("com.taobao.find.xsign", obj);
|
|||
|
if (_app != null && _app.ok)
|
|||
|
{
|
|||
|
obj["x-sign"] = (_app.message as Dictionary<string, object>)["result"].ToString();
|
|||
|
HttpHelper http = new HttpHelper();
|
|||
|
var result = _app.message as Dictionary<string, object>;
|
|||
|
var item = new HttpItem();
|
|||
|
var header = @"x-appkey:[appkey]
|
|||
|
x-features:[x-features]
|
|||
|
x-t:[x-t]
|
|||
|
x-pv:5.1
|
|||
|
x-location:116.410344%2C39.916295
|
|||
|
x-ttid:[x-ttid]
|
|||
|
x-utdid:[x-utdid]
|
|||
|
x-devid:[x-devid]
|
|||
|
x-sign:[x-sign]
|
|||
|
x-page-url:http%3A%2F%2Fitem.taobao.com%2Fitem.htm
|
|||
|
x-unitinfo:center";
|
|||
|
foreach (var _temp in obj)
|
|||
|
{
|
|||
|
header = header.Replace("[" + _temp.Key + "]", _temp.Value.ToString());
|
|||
|
}
|
|||
|
var headers = header.Split(new string[] { "\r\n" }, StringSplitOptions.None);
|
|||
|
foreach (var val in headers)
|
|||
|
{
|
|||
|
var s = val.Split(':');
|
|||
|
item.Header[s[0]] = s[1].Trim();
|
|||
|
}
|
|||
|
_data = UrlEncode(_data);
|
|||
|
item.URL = "https://acs.m.taobao.com/gw/" + api + "/" + v + "/?data=" + _data.Replace("\\u0026", "&");
|
|||
|
item.Timeout = 5000;
|
|||
|
var temp = http.GetHtml(item);
|
|||
|
return temp.Html;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
catch
|
|||
|
{ }
|
|||
|
return null;
|
|||
|
}
|
|||
|
private string UrlEncode(string str)
|
|||
|
{
|
|||
|
StringBuilder builder = new StringBuilder();
|
|||
|
foreach (char c in str)
|
|||
|
{
|
|||
|
if (HttpUtility.UrlEncode(c.ToString()).Length > 1)
|
|||
|
{
|
|||
|
builder.Append(HttpUtility.UrlEncode(c.ToString()).ToUpper());
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
builder.Append(c);
|
|||
|
}
|
|||
|
}
|
|||
|
return builder.ToString();
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
/// 发送API数据
|
|||
|
/// </summary>
|
|||
|
/// <param name="method">API接口</param>
|
|||
|
/// <param name="param">参数</param>
|
|||
|
/// <returns></returns>
|
|||
|
private WebResult SendData(string method, object param = null)
|
|||
|
{
|
|||
|
int num = 0;
|
|||
|
Next:
|
|||
|
try
|
|||
|
{
|
|||
|
AuthEndpoint end = new AuthEndpoint()
|
|||
|
{
|
|||
|
Appid = _appid,
|
|||
|
Enckey = _key,
|
|||
|
Host = _host + "/api/alimama.asmx/send_data",
|
|||
|
Method = method
|
|||
|
};
|
|||
|
if (param != null)
|
|||
|
{
|
|||
|
if (param.GetType() == typeof(Dictionary<string, object>))
|
|||
|
{
|
|||
|
|
|||
|
foreach (var item in param as Dictionary<string, object>)
|
|||
|
{
|
|||
|
end.Param[item.Key] = item.Value;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
var _param = param.GetType().GetProperties();
|
|||
|
foreach (var item in _param)
|
|||
|
{
|
|||
|
end.Param[item.Name] = item.GetValue(param);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
HttpHelper http = new HttpHelper(); return http.SendData(end, true);
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
if (ex.Message == "未将对象引用设置到对象的实例。" && num < 2)
|
|||
|
{
|
|||
|
num++;
|
|||
|
goto Next;
|
|||
|
}
|
|||
|
return new CsharpHttpHelper.WebResult() { ok = false, message = ex.Message };
|
|||
|
}
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 将c# DateTime时间格式转换为Unix时间戳格式
|
|||
|
/// </summary>
|
|||
|
/// <param name="time">时间</param>
|
|||
|
/// <returns>long</returns>
|
|||
|
private static long ConvertDateTimeToInt(System.DateTime time)
|
|||
|
{
|
|||
|
System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1, 0, 0, 0, 0));
|
|||
|
long t = (time.Ticks - startTime.Ticks) / 10000; //除10000调整为13位
|
|||
|
return t;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
#region 获取评价标签Tag
|
|||
|
/// <summary>
|
|||
|
/// 通过宝贝id获取宝贝评价标签集合
|
|||
|
/// </summary>
|
|||
|
/// <param name="itemId">宝贝id</param>
|
|||
|
/// <returns>返回标签集合</returns>
|
|||
|
public static List<TagCloud> FindTagsByItemId(string itemId)
|
|||
|
{
|
|||
|
int count = 0;
|
|||
|
Go:
|
|||
|
try
|
|||
|
{
|
|||
|
//var item = GetItem("https://rate.tmall.com/listTagClouds.htm?itemId=" + itemId + "&isAll=true&isInner=true&t=" + ConvertDateTimeToInt(DateTime.Now) + "&_ksTS=" + ConvertDateTimeToInt(DateTime.Now) + "_1892&callback=jsonp1893", Encoding.UTF8);
|
|||
|
//GetHtml(item);
|
|||
|
|
|||
|
HttpHelper http = new HttpHelper();
|
|||
|
var item = http.GetItem("https://rate.tmall.com/listTagClouds.htm?itemId=" + itemId + "&isAll=true&isInner=true&t=" + ConvertDateTimeToInt(DateTime.Now) + "&_ksTS=" + ConvertDateTimeToInt(DateTime.Now) + "_1892&callback=jsonp1893", RandomTbCookies());
|
|||
|
item.Allowautoredirect = true;
|
|||
|
item.Encoding = Encoding.UTF8;
|
|||
|
var rest = http.GetHtml(item);
|
|||
|
string html = rest.Html.Replace("jsonp1893(", "").Replace(")", "").Trim();
|
|||
|
//{"tags":{"rateSum":0,"structuredRateStatisticList":[],"tagClouds":[],"dimenSum":0,"innerTagCloudList":[],"userTagCloudList":[]}}
|
|||
|
var dic = HttpExtend.JsonToDictionary(html) as Dictionary<string, object>;
|
|||
|
if (dic == null) throw new Exception("获取Tag失败。");
|
|||
|
if (!dic.ContainsKey("tags")) throw new Exception("不包含tags:" + html);
|
|||
|
var tags = dic["tags"] as Dictionary<string, object>;
|
|||
|
if (!tags.ContainsKey("tagClouds")) throw new Exception("不包含tagClouds:" + html);
|
|||
|
|
|||
|
var clouds = HttpHelper.JsonToObject<TagCloud[]>(HttpHelper.ObjectToJson(tags["tagClouds"])) as TagCloud[];
|
|||
|
return clouds.ToList();
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
if (count <= 3)
|
|||
|
{
|
|||
|
count++;
|
|||
|
Thread.Sleep(150);
|
|||
|
goto Go;
|
|||
|
}
|
|||
|
throw ex;
|
|||
|
}
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 获取要保存的评价内容
|
|||
|
/// </summary>
|
|||
|
/// <param name="commentContents"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public static string GetCommentContents(List<string> commentContents)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
StringBuilder strb = new StringBuilder();
|
|||
|
//这里是随机取10条数据
|
|||
|
for (int i = 0; i < 16; i++)
|
|||
|
{
|
|||
|
if (commentContents.Count > i && commentContents[i] != null && !string.IsNullOrEmpty(commentContents[i]))
|
|||
|
{
|
|||
|
var positions = commentContents[i].Trim().Split(new string[] { ",", ",", "。", "?", "?", "!", "!", "~", " " }, StringSplitOptions.RemoveEmptyEntries);
|
|||
|
if (positions.Length != 0)
|
|||
|
strb.Append(positions[new Random().Next(0, positions.Length)] + (new Random().Next(0, 2) == 1 ? "。" : ","));
|
|||
|
}
|
|||
|
}
|
|||
|
return strb.ToString();
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
return string.Empty;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
}
|