Files
29WxOrder/Work/TaobaoMobileCollect.cs
2026-06-11 15:17:50 +08:00

635 lines
27 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 System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using AllBase;
namespace Work
{
public class TaobaoMobileCollect
{
public string Name, Content;
public bool IsUrlCollect = false, Pinduoduo = false;
public bool IsUpdateSku = false, ThisShopId = false;
public bool GetSuccess = false, NoTemp = false, Delete = false, NoContent = false;
public decimal BeforePrice = 0;
public static Dictionary<long, ProductCollectBase> ProductTemp = new Dictionary<long, ProductCollectBase>();
public ProductCollectBase Product;
public TaobaoMobileCollect(ProductCollectBase product)
{
Product = product;
}
public void Get()
{
if (ProductTemp.ContainsKey(Product.from_id))
{
Product = ProductTemp[Product.from_id].Clone();
return;
}
GetSuccess = false;
Delete = false;
string urlProduct = "http://acs.m.taobao.com/h5/mtop.taobao.detail.getdetail/6.0/?api=mtop.taobao.detail.getdetail&v=6.0&ttid=2016%40taobao_h5_2.0.0&isSec=0&ecode=0&AntiFlood=true&AntiCreep=true&H5Request=true&type=jsonp&dataType=jsonp&callback=mtopjsonp1&data=%7B%22exParams%22%3A%22%7B%5C%22id%5C%22%3A%5C%22549564635405%5C%22%7D%22%2C%22itemNumId%22%3A%22" + (ThisShopId ? Product.id : Product.from_id) + "%22%7D";
bool nokey = false, hadFile = false;
string content = "", newContent = "";
string refere = "https://h5.m.taobao.com/awp/core/detail.htm?id=" + (ThisShopId ? Product.id : Product.from_id);
//string html =NoTemp?"": TempFileReadWrite.Read(Product.id, "content", out hadFile);
//if(string.IsNullOrEmpty(html))
// html = GetPostTaobaoHtml.UploadTaobao(urlProduct, refere, true);
string html = GetPostTaobaoHtml.UploadTaobao(urlProduct, refere, true);
if (string.IsNullOrEmpty(html) || !html.Contains("调用成功"))
{
Thread.Sleep(10000);
html = GetPostTaobaoHtml.UploadTaobao(urlProduct, refere, true);
}
if (string.IsNullOrEmpty(html) || !html.Contains("调用成功"))
{
Thread.Sleep(20000);
html = GetPostTaobaoHtml.UploadTaobao(urlProduct, refere, true);
}
if (string.IsNullOrEmpty(html) || !html.Contains("调用成功"))
{
LogSave.Add(Name, "读取页面失败:" + urlProduct);
return;
}
if (string.IsNullOrEmpty(html) || html.Contains("redirectUrl"))
{
LogSave.Add(Name, "宝贝已经下架:" + urlProduct);
return;
}
//if (!hadFile)
// TempFileReadWrite.Write(Product.id, "content",html);
GetSuccess = true;
html = GetHtml.Decode(html).Replace("\\\"", "\"").Replace("\\\\", "\\");
Product.name = BaseRegex.GetMatchRegexString(ref html, @"""item"":\{[^\}]*?""title"":""([^""]+)""");
if (string.IsNullOrEmpty(Product.name))
{
BigDataBuildDelete(Product.from_id, 1);
if (IsUpdateSku)
{
Delete = true;
LogSave.Add(Name, "上家已经删除:" + (ThisShopId ? Product.id : Product.from_id));
}
else
{
LogSave.Add(Name, "标题获取错误:" + Product.from_url);
}
return;
}
string pricex = BaseRegex.GetMatchRegexString(ref html,
@"""price"":\{""price"":\{""priceMoney"":""[\d]+"",""priceText"":""([\d\.]+)""");
if (string.IsNullOrEmpty(pricex))
pricex = BaseRegex.GetMatchRegexString(ref html,
@"""price"":\{""price"":\{""priceText"":""([\d\.]+)");
string price_beforex = BaseRegex.GetMatchRegexString(ref html,
@"""extraPrices"":\[\{""priceMoney"":""[\d]+"",""priceText"":""([\d\.]+)""");
if (string.IsNullOrEmpty(price_beforex))
{
price_beforex = pricex;
}
if (price_beforex == "0" || string.IsNullOrEmpty(price_beforex))
{
LogSave.Add("价格为空,退出:" + Product.from_url);
return;
}
Product.saleCount = BaseRegex.GetIntJson(ref html, "sellCount");
string eprice = BaseRegex.GetMatchRegexString(ref html, @"""postage"":""快递[::][\s]*([\d\.]+)元");
Product.express_price = string.IsNullOrEmpty(eprice) ? 0 : decimal.Parse(eprice);
Product.price = decimal.Parse(pricex);
Product.num = BaseRegex.GetIntJson(ref html, "num");
Product.from_shop_name = BaseRegex.GetStringJson(ref html, "sellerNick");
if (Product.num == 0)
{
string num = BaseRegex.GetMatchRegexString(ref html, @"""skuCore"":[\w\W]+?""quantity"":""([\d]+)""");
if (!string.IsNullOrEmpty(num))
Product.num = int.Parse(num);
}
Product.discountPrice = decimal.Parse(pricex);
Product.before_price = decimal.Parse(price_beforex);
Product.discount = Product.discountPrice / Product.before_price;//折扣比例
Product.onlinePrice = Product.discountPrice * Product.shopAddPercent / 100 + new Random(Guid.NewGuid().GetHashCode()).Next((int)(Product.shopAddPriceMin * 100),
(int)(Product.shopAddPriceMax * 100)) / 100;
if (IsUrlCollect)
{
Product.onlinePrice = GetOnlinePrice(Product.price);
}
if (IsUpdateSku)//如果是更新SKU则直接跳转到SKU部分
{
goto GetSku;
}
string catId = BaseRegex.GetStringJson(ref html, @"categoryId");
catId = string.IsNullOrEmpty(catId) ? BaseRegex.GetMatchRegexString(ref html, @"categoryId:([\d]+)") : catId;
if (catId.Contains(","))
catId = catId.Substring(catId.LastIndexOf(",") + 1);
Product.cat_id = int.Parse(catId);
Product.main_cid = BaseRegex.GetIntJson(ref html, @"rootCategoryId");
Product.from_cat_id = Product.cat_id;
Product.from_site_id = 1;
if (Product.main_cid == 0)
{
LogSave.Add(Name, "没有找到主分类:" + Product.from_url);
return;
}
//===================标题过滤======================
string title = Product.name.ToLower();
long md5 = BaseClass.GetLong(Product.name);
foreach (string s in BaseClass.CantTitleKeywords)
{
if (title.Contains(s))
{
nokey = true;
LogSave.Add(Name, s + " : " + title);
break;
}
}
foreach (string s in BaseClass.CantTitle)
{
if (title.Contains(s))
{
nokey = true;
LogSave.Add(Name, s + " : " + title);
break;
}
}
foreach (string s in BaseClass.CantCatId)
{
if (Product.cat_id.ToString() == s || Product.main_cid.ToString() == s)
{
nokey = true;
LogSave.Add(Name, s + " : " + title);
break;
}
}
//string url = "https://hws.m.taobao.com/cache/desc/5.0?callback=backToDesc&id=" + Product.from_id + "&type=0";
long time;
string data = "data={\"id\":\"" + Product.from_id + "\",\"type\":\"0\"}";
string sign = GetSign("", data, out time);
//获取订单详情描述内容
string url = "https://h5api.m.taobao.com/h5/mtop.taobao.detail.getdesc/6.0/?jsv=2.5.1&appKey=12574478&t=1555394927537&sign=" + sign + "&api=mtop.taobao.detail.getdesc&v=6.0&isSec=0&ecode=0&AntiFlood=true&AntiCreep=true&H5Request=true&type=jsonp&dataType=jsonp&callback=mtopjsonp3&data={\"id\":\"" + Product.from_id + "\",\"type\":\"0\"}";
//content = TempFileReadWrite.Read(Product.id, "desc",out hadFile);
//if(string.IsNullOrEmpty(content))
if (NoContent)
{
content = "不需要描述";
}
else
{
content = GetPostTaobaoHtml.UploadTaobao(url, refere, true);
if (string.IsNullOrEmpty(content))
{
Thread.Sleep(10000);
content = GetPostTaobaoHtml.UploadTaobao(url, refere, true);
}
//if (!hadFile)
// TempFileReadWrite.Write(Product.id, "desc", content);
string tempx = BaseRegex.GetMatchRegexString(ref content, @"""wdescContent"":""([\w\W]+?)"",""anchors");
if (string.IsNullOrEmpty(tempx))
tempx = BaseRegex.GetMatchRegexString(ref content, "\"wdescContent\":([\\W\\w]+)");
//tempx = BaseRegex.GetMatchRegexString(ref content, @"""wdescContent"":""([\w\W]+?)"",""");
if (string.IsNullOrEmpty(tempx))
{
LogSave.Add(Name, "描述正文正则失败,跳过 " + url);
return;
}
content = tempx.Replace("\\\"", "\"").Replace("\\\\", "\\");
}
//识别上家ID
Product.upShopId = GetUpId(ref content);
newContent = ClearContent(content);
if (string.IsNullOrEmpty(content) || string.IsNullOrEmpty(newContent))
{
LogSave.Add(Name, "描述正文为空,跳过 " + url);
return;
}
Content = newContent;
Product.content = Content;
Product.item_size = "";
Product.item_weight = 1;
Product.state = "浙江";
Product.city = "杭州";
string address = BaseRegex.GetMatchRegexString(ref html, @"""delivery"":\{""from"":""([^""]+?)""");
if (string.IsNullOrEmpty(address))
address = BaseRegex.GetStringJson(ref html, @"location");
string[] provice =
"上海,北京,天津,重庆,黑龙江,辽宁,内蒙古,吉林,河北,河南,山西,山东,陕西,青海,宁夏,甘肃,新疆,西藏,四川,云南,贵州,广西,湖南,湖北,安徽,江苏,浙江,广东,福建,海南,台湾,香港,澳门".Split(',');
string[] city =
"上海,北京,天津,重庆,哈尔滨,沈阳,呼和浩特,长春,石家庄,郑州,太远,济南,西安,西宁,银川,兰州,乌鲁木齐,拉萨,成都,昆明,贵阳,南宁,长沙,武汉,合肥,南京,杭州,广州,福州,海口,台北,香港,澳门".Split(',');
if (!string.IsNullOrEmpty(address))
{
for (int i = 0; i < provice.Length; i++)
{
if (address.Contains(provice[i]))
{
Product.state = provice[i];
Product.city = city[i];
break;
}
}
}
string temp = BaseRegex.GetMatchRegexString(ref html, @",""images"":\[([^\]]+?)\]");
if (string.IsNullOrEmpty(temp))
{
LogSave.Add(Name, "图片错误:" + Product.from_url);
return;
}
var m = BaseRegex.GetMatchRegex(ref temp, @"""([^""]+)""");
if (m.Count == 0)
{
LogSave.Add(Name, "图片错误:" + Product.from_url);
return;
}
for (int i = 0; i < m.Count; i++)
{
Product.Images.Add(m[i].Groups[1].Value);
}
Product.image = Product.Images[0];
Product.image_from_url = Product.Images[0];
temp = BaseRegex.GetMatchRegexString(ref html, @"""props"":\{""groupProps"":([\w\W]+?)\]\},");
if (!string.IsNullOrEmpty(temp))
{
m = BaseRegex.GetMatchRegex(ref temp, @"\{""([^""]+)"":""([^""]+)""\}");
if (m.Count == 0)
{
LogSave.Add("参数错误:" + Product.from_url);
return;
}
for (int i = 0; i < m.Count; i++)
{
string name = m[i].Groups[1].Value;
string value = m[i].Groups[2].Value;
if (name.Length > 50 || value.Length > 50)
continue;
Product.Prop.Add(new KeyValueBase(name, value));
}
}
GetSku:
bool hadPrice = false;
m = BaseRegex.GetMatchRegex(ref html,
@"\{""pid"":""([\d]+)"",""name"":""([^""]+)"",""values"":\[([\w\W]+?)\]\}");
for (int i = 0; i < m.Count; i++)
{
PropBase p = new PropBase();
p.id = long.Parse(m[i].Groups[1].Value);
p.name = m[i].Groups[2].Value;
p.name = BaseRegex.Relpace(p.name, "(&[a-zA-z0-9]+?;)", "");
bool had = false;
for (int j = 0; j < Product.Props.Count; j++)
{
if (Product.Props[j].name == p.name)
{
p = Product.Props[j];
had = true;
break;
}
}
temp = m[i].Groups[3].Value;
var mm = BaseRegex.GetMatchRegex(ref temp, @"""vid"":""([\d]+?)"",""name"":""([^""]+?)""[^\}]*\}");
for (int j = 0; j < mm.Count; j++)
{
string v = mm[j].Groups[1].Value;
string vi = mm[j].Groups[0].Value;
string image = BaseRegex.GetStringJson(ref vi, "image");
PropValueBase pr = new PropValueBase();
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;
bool hadx = false;
for (int k = 0; k < p.Values.Count; k++)
{
if (p.Values[k].name == pr.name)
{
hadx = true;
break;
}
}
if (!hadx)
p.Values.Add(pr);
}
if (!had)
{
p.sort = i + 1;
Product.Props.Add(p);
}
}
m = BaseRegex.GetMatchRegex(ref html, @"""skuId"":""([\d]+)"",""propPath"":""([-\d:;]+)""");
for (int i = 0; i < m.Count; i++)
{
string skuid = m[i].Groups[1].Value;
string skuValues = m[i].Groups[2].Value;
var mm = BaseRegex.GetMatchRegex(ref html,
@"""" + skuid + @""":[^\}]+?""priceText"":""([\d.]+)""[^\}]*?},""quantity"":([\d]+)\}");
if (mm.Count == 0)
{
LogSave.Add("SKU识别错误:" + Product.from_url);
continue;
}
string priceText = mm[0].Groups[1].Value;
decimal before_price = decimal.Parse(priceText);
decimal price = before_price;
string numberString = BaseRegex.GetMatchRegexString(ref html,
@"""" + skuid + @""":[\w\W]+?""quantity"":""([\d]+)""");
int number = 0;
if (!string.IsNullOrEmpty(numberString))
number = int.Parse(numberString);
if (number > 100)
number = 100;
string name = BuildName(skuValues);
if (string.IsNullOrEmpty(name))
continue;
bool had = false;
for (int j = 0; j < Product.SkuMaps.Count; j++)
{
if (Product.SkuMaps[j].name == name)
{
had = true;
break;
}
}
if (had)
{
continue;
}
mm = BaseRegex.GetMatchRegex(ref html,
@"""" + skuid + @""":[^\}]+?""priceText"":""([\d.]+)"",""(type|showTitle|sugProm|priceMoney)""");
if (mm.Count != 0)
{
price = decimal.Parse(mm[0].Groups[1].Value);//这是折扣后的价格
if (before_price != 0)
{
decimal dic = price / before_price;
if (dic < Product.discount)
Product.discount = dic;
}
}
SkuMapBase sm = new SkuMapBase();
sm.id = long.Parse(skuid);
sm.name = name;
sm.price = price;
sm.online_price = sm.price * Product.shopAddPercent / 100 +
new Random(Guid.NewGuid().GetHashCode()).Next((int)(Product.shopAddPriceMin * 100),
(int)(Product.shopAddPriceMax * 100)) / 100;
if (!Pinduoduo && (price < BaseClass.MinPrice || price > BaseClass.MaxPrice))
number = 0;
else
hadPrice = true;
if (IsUrlCollect)
{
sm.online_price = GetOnlinePrice(sm.price);
}
sm.number = number;
sm.before_price = before_price;
sm.sale_count = 0;
Product.SkuMaps.Add(sm);
}
for (int i = 0; Product.discount < 1 && i < Product.SkuMaps.Count; i++)
{
if (Product.SkuMaps[i].number == 0)
Product.SkuMaps[i].price = Decimal.Round(Product.discount * Product.SkuMaps[i].before_price, 2);
}
try
{
if (!ProductTemp.ContainsKey(Product.from_id))
ProductTemp.Add(Product.from_id, Product);
}
catch
{
}
if (!hadPrice && (Product.price < (IsUpdateSku ? BaseClass.MinPrice * 0.8m : BaseClass.MinPrice) || Product.price > BaseClass.MaxPrice))
{
//LogSave.Add(Name, "价格太低:" + Product.from_url);
//if (IsUpdateSku)
//{
// SetSku( 0, 0, 5);
//}
//else
//{
// return;
//}
}
//if (IsUpdateSku || Pinduoduo)//如果是更新上家价格,则执行此代码
//{
// Product.main_cid = new FromTitleToCat().GetMainCatId(Product.cat1);
// if(Product.main_cid==0)
// return;
// url = BaseClass.BigDataApiUrl + "?obj=product/product";
// string datax = "&act=update&site_id=1&shop_name=" + GetHtml.UrlEncodeUtf8(Product.from_shop_name) + "&json=" + GetHtml.UrlEncodeUtf8(JsonHelper.SerializeObject(Product));
// html = GetHtml.PostUtf8(url, UserLogin.GetSignaturex() + datax);
// //后期加代码
// return;
//}
//淘宝大数据收集
//string json = JsonHelper.SerializeObject(Product);
//string data = "id=" + Product.id + "&site_id=" + Product.from_site_id + "&" + UserLogin.GetSignaturex() +
// "&json=" + GetHtml.UrlEncodeUtf8(json);
//string upUrl = BaseClass.BuildObjString("upload_data");
//html = GetHtml.PostUtf8(upUrl, data);
if (nokey)//过滤数据
return;
if (html == "Ok" || html == "Had")
{
LogSave.Add(Name, "采集成功:" + Product.id);
}
Product.from_title = Product.name;
}
/// <summary>
/// 淘宝签名算法
/// </summary>
/// <param name="h5Tk"></param>
/// <param name="data"></param>
/// <returns></returns>
public string GetSign(string h5Tk, string data, out long time)
{
string appkey = "12574478";
System.DateTime starttime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); // 当地时区
DateTime datetime = DateTime.Now;
time = (long)(datetime - starttime).TotalMilliseconds; // 相差毫秒数
string code = h5Tk + "&" + time + "&" + appkey + "&" + data;
return Md5Base.GetMd5(code).ToLower();
}
/// <summary>
/// 生成名称
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
private string BuildName(string name)
{
string temp = "";
for (int i = 0; i < Product.Props.Count; i++)
{
for (int j = 0; j < Product.Props[i].Values.Count; j++)
{
if (name.Contains(Product.Props[i].Values[j].value))
{
temp += Product.Props[i].name + ":" + Product.Props[i].Values[j].name + ";";
break;
}
}
}
if (string.IsNullOrEmpty(temp))
return "";
return temp.Substring(0, temp.Length - 1);
}
/// <summary>
/// 网址采集计算价格
/// </summary>
/// <param name="price"></param>
/// <returns></returns>
public decimal GetOnlinePrice(decimal price)
{
if (price < 40)
{
price = price * 100 + new Random(Guid.NewGuid().GetHashCode()).Next(1500, 2000);
}
else if (price < 100)
{
price = price * 100 + new Random(Guid.NewGuid().GetHashCode()).Next(2500, 3000);
}
else if (price < 200)
{
price = price * 100 + new Random(Guid.NewGuid().GetHashCode()).Next(3000, 5000);
}
else
{
price = price * 100 + new Random(Guid.NewGuid().GetHashCode()).Next(4000, 6000);
}
return price / 100;
}
/// <summary>
/// 获取上家ID
/// </summary>
/// <param name="content"></param>
/// <returns></returns>
public static long GetUpId(ref string content)
{
string upShopId = BaseRegex.GetMatchRegexString(ref content, @"//item\.taobao\.com/item\.htm\?id=([345][\d]{11})[\D]");
if (string.IsNullOrEmpty(upShopId))
upShopId = BaseRegex.GetMatchRegexString(ref content, @"<[^>]*#fff[^>]*>[^<]*([345][\d]{11})[\D]");
if (string.IsNullOrEmpty(upShopId))
upShopId = BaseRegex.GetMatchRegexString(ref content, @"<[^>]*white[^>]*>[^<]*([345][\d]{11})[\D]");
if (string.IsNullOrEmpty(upShopId))
upShopId = BaseRegex.GetMatchRegexString(ref content, @"<[^>]*#ffffff[^>]*>[^<]*([345][\d]{11})[\D]");
if (string.IsNullOrEmpty(upShopId) && content.Length > 100)
upShopId = BaseRegex.GetMatchRegexString(content.Substring(0, 100), @"[\D]([345][\d]{11})[\D]");
if (string.IsNullOrEmpty(upShopId))
upShopId = BaseRegex.GetMatchRegexString(ref content, @"//item\.taobao\.com/item\.htm\?id=[\D]([\d]{11,12})[\D]");
if (string.IsNullOrEmpty(upShopId))
upShopId = BaseRegex.GetMatchRegexString(ref content, @"[\D]([\d]{11,12})[\D]");
if (string.IsNullOrEmpty(upShopId))
upShopId = BaseRegex.GetMatchRegexString(ref content, @"[\D]([\d]{6,12})[\D]");
if (string.IsNullOrEmpty(upShopId))
upShopId = "0";
return long.Parse(upShopId);
}
/// <summary>
/// 清理正文
/// </summary>
/// <param name="content"></param>
/// <returns></returns>
public static string ClearContent(string content)
{
string newContent = BaseRegex.Relpace(content, @"(<img[^>]*assets\.alicdn\.com[^>]*>)", "");
ClearTable(ref newContent);
BaseRegex.Relpace(ref newContent, @"(<[aA] [\w\W]+?</[aA]>)", "");
BaseRegex.Relpace(ref newContent, @"(<p[^>]*>[^<]*[\d]{10,15}[^<]*</p>)", "");
BaseRegex.Relpace(ref newContent, @"(<[^>]*#ffffff[^>]*>[^<]*[\d]{10,15}[^<]*<[^>]*>)", "");
BaseRegex.Relpace(ref newContent, @"((<[pdiv]+[^>]*width:[\s]*0;[\s]*height:[\s]*0;[^>]*>[\w\W]*?</[pdiv]+>))", "");
BaseRegex.Relpace(ref newContent, @"((<[pdiv]+[^>]*width:[\s]*0px;[\s]*height:[\s]*0px;[^>]*>[\w\W]*?</[pdiv]+>))", "");
BaseRegex.Relpace(ref newContent, @"(http[\s]{0,1}://item\.taobao\.com/item\.htm\?id=[\d]+)", "");
newContent = newContent.Replace("<p>&nbsp;</p>", "");
if (!newContent.Contains("<img "))
return content;
return newContent;
}
/// <summary>
/// 清除表格广告代码
/// </summary>
/// <param name="html"></param>
/// <returns></returns>
public static void ClearTable(ref string html)
{
if (string.IsNullOrEmpty(html))
return;
int i = html.IndexOf("<table");
Again:
int first = i;
if (i < 0)
return;
int end = html.IndexOf("</table", i);
if (i < 0 || end < 0 || end < i)
return;
int top = 1;
while (top > 0 && i >= 0)
{
end = html.IndexOf("</table", i);
string temp = html.Substring(i + 6, end - i + 2);
int add = (temp.Length - temp.Replace("<table", "").Length) / 6;
top = top - 1 + add;
int t1 = html.IndexOf("<table", end + 7);
int t2 = html.IndexOf("</table", end + 7);
if (t1 >= 0 && (t1 < t2 || t2 < 0))
i = t1;
if (t2 >= 0 && (t2 < t1 || t1 < 0))
i = t2;
}
string re = html.Substring(first, end - first + 8);
if (re.Contains("<a "))
{
html = html.Replace(re, "");
i = html.IndexOf("<table");
}
else
{
i = html.IndexOf("<table", end);
}
goto Again;
}
public static void BigDataBuildDelete(long id, int site)
{
return;
string url = BaseClass.BigDataApiUrl + "?obj=product/product";
string data = "&act=delete&site_id=" + site + "&id=" + id;
string html = GetHtml.PostUtf8(url, UserLogin.GetSignaturex() + data);
}
}
}