327 lines
16 KiB
C#
327 lines
16 KiB
C#
using AllBase;
|
|
using AllBase.Helper;
|
|
using AllBase.Model.Result;
|
|
using TemuKJD.KJDForms.ToolForms;
|
|
using NaiBa.Util.Extension;
|
|
using Newtonsoft.Json.Linq;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Data;
|
|
using System.Drawing;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
|
|
namespace TemuKJD.KJDForms.CollectForms
|
|
{
|
|
public partial class CaiNiXiHuanCollectForm : Form
|
|
{
|
|
decimal priceMin = 0;
|
|
decimal priceMax = 99999999;
|
|
long sellCountMin = 0;
|
|
long sellCountMax = 99999999;
|
|
long commentCountMin = 0;
|
|
long commentCountMax = 99999999;
|
|
int rateMin = 0;
|
|
int rateMax = 100;
|
|
List<DouGoodsCollectInfo> lstProduct = new List<DouGoodsCollectInfo>();
|
|
CancellationTokenSource cancellationTokenSource = null;
|
|
|
|
public CaiNiXiHuanCollectForm()
|
|
{
|
|
InitializeComponent();
|
|
}
|
|
|
|
private void btnCollect_Click(object sender, EventArgs e)
|
|
{
|
|
if (btnCollect.Text != "开始采集")
|
|
{
|
|
cancellationTokenSource.Cancel();
|
|
}
|
|
else
|
|
{
|
|
var cookieShop = GlobalConfig.ShopLoginList.FirstOrDefault(s => s.LoginStatus == "登录成功");
|
|
if (cookieShop == null)
|
|
{
|
|
BaseForms.BaseMsgForm.ShowError("请登录店铺账号后搜索");
|
|
return;
|
|
}
|
|
|
|
priceMin = this.txtPriceMin.Text.ParseToDecimal();
|
|
priceMax = this.txtPriceMax.Text.ParseToDecimal();
|
|
sellCountMin = this.txtSellCountMin.Text.ParseToLong();
|
|
sellCountMax = this.txtSellCountMax.Text.ParseToLong();
|
|
commentCountMin = this.txtCommentCountMin.Text.ParseToLong();
|
|
commentCountMax = this.txtCommentCountMax.Text.ParseToLong();
|
|
rateMin = this.txtRateMin.Text.ParseToInt();
|
|
rateMax = this.txtRateMax.Text.ParseToInt();
|
|
|
|
int pageTotal = txtTotalPage.Text.ParseToInt();
|
|
if (pageTotal < 1)
|
|
{
|
|
BaseForms.BaseMsgForm.ShowError("请至少查询一页以上数据");
|
|
return;
|
|
}
|
|
var searchTextArr = this.txtKeyWords.Text.Split(new string[] { "\r", "\n", ",", " " }, StringSplitOptions.RemoveEmptyEntries);
|
|
if (searchTextArr.Length == 0)
|
|
{
|
|
searchTextArr = new string[] { "" };
|
|
//BaseForms.BaseMsgForm.ShowError("请至少输入一个商品");
|
|
//return;
|
|
}
|
|
lstProduct.Clear();
|
|
this.dgvCollect.Rows.Clear();
|
|
cancellationTokenSource = new CancellationTokenSource();
|
|
int n = 0;
|
|
int total = searchTextArr.Count() * pageTotal;
|
|
this.statusBar.lblTaskStatus.Text = "开始采集...";
|
|
this.statusBar.pgbTaskProgress.Value = n;
|
|
this.statusBar.pgbTaskProgress.Text = n + "/" + total;
|
|
this.statusBar.pgbTaskProgress.Maximum = total;
|
|
btnCollect.Text = "停止采集";
|
|
|
|
Task.Run(() =>
|
|
{
|
|
if (!Directory.Exists("采集导出"))
|
|
Directory.CreateDirectory("采集导出");
|
|
var exportFileName = "采集导出\\猜你喜欢采集" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".csv";
|
|
StreamWriter writer = new StreamWriter(exportFileName, true, Encoding.GetEncoding("gb2312"));
|
|
object[] objArray1 = new object[] { "商品ID,", "商品名称,", "价格,", "销量,", "评论数,", "好评率" };
|
|
writer.WriteLine(string.Concat(objArray1));
|
|
writer.Close();
|
|
|
|
foreach (var searchText in searchTextArr)
|
|
{
|
|
if (cancellationTokenSource.IsCancellationRequested)
|
|
break;
|
|
|
|
var text = searchText;
|
|
if (text.ParseToLong() == 0)
|
|
text = BaseRegex.GetMatchRegexString(ref text, "(\\d{10,22})");
|
|
for (int i = 1; i < pageTotal + 1; i++)
|
|
{
|
|
n++;
|
|
Invoke(new Action(() =>
|
|
{
|
|
this.statusBar.lblTaskStatus.Text = "正在采集商品" + text + "猜你喜欢,当前采集到第 " + i + " 页";
|
|
this.statusBar.pgbTaskProgress.Value = n;
|
|
this.statusBar.pgbTaskProgress.Text = n + "/" + total;
|
|
this.statusBar.pgbTaskProgress.Maximum = total;
|
|
}));
|
|
Thread.Sleep(Randomx.GetId(100, 500));
|
|
int pageNum = i;
|
|
var cnxhResult = CollectCaiNiXiHuan(cookieShop.Cookies, text, pageNum.ToString());
|
|
if (!string.IsNullOrEmpty(cnxhResult) && cnxhResult.Contains("\"status_code\":0"))
|
|
{
|
|
JObject jObj = JObject.Parse(cnxhResult);
|
|
if (jObj["item_cards"] == null)
|
|
return;
|
|
foreach (JObject pObj in jObj["item_cards"])
|
|
{
|
|
if (cancellationTokenSource.IsCancellationRequested)
|
|
break;
|
|
|
|
var pStr = JsonHelper.SerializeObject(pObj);
|
|
var pId = BaseRegex.GetStringJson(ref pStr, "product_id");
|
|
if (!string.IsNullOrEmpty(pId))
|
|
{
|
|
DouGoodsCollectInfo prod = new DouGoodsCollectInfo();
|
|
prod.Id = pId;
|
|
prod.GoodsName = BaseRegex.GetStringJson(ref pStr, "title");
|
|
if (string.IsNullOrEmpty(prod.GoodsName))
|
|
{
|
|
}
|
|
prod.Price = (BaseRegex.GetDecimalJson(ref pStr, "min_price") / 100).ToString();
|
|
prod.Sales = BaseRegex.GetIntJson(ref pStr, "sales").ToString();
|
|
|
|
// 筛选条件
|
|
if (prod.Price.ParseToDecimal() < this.priceMin || prod.Price.ParseToDecimal() > this.priceMax
|
|
|| prod.Sales.ParseToDecimal() < this.sellCountMin || prod.Sales.ParseToDecimal() > this.sellCountMax)
|
|
continue;
|
|
|
|
Thread.Sleep(Randomx.GetId(500, 1000));
|
|
var commentResult = GetComments(GlobalConfig.DouUserCookies, prod.Id);
|
|
if (!string.IsNullOrEmpty(commentResult) && commentResult.Contains("\"status_code\":0"))
|
|
{
|
|
prod.CommentsCount = BaseRegex.GetIntJson(ref commentResult, "total_comments_num");
|
|
prod.CommentsRate = BaseRegex.GetDecimalJson(ref commentResult, "good_comment_ratio").ParseToDouble() / 100;
|
|
}
|
|
|
|
// 筛选条件
|
|
if (prod.CommentsRate < this.rateMin || prod.CommentsRate > this.rateMax
|
|
|| prod.CommentsCount < this.commentCountMin || prod.CommentsCount > this.commentCountMax)
|
|
continue;
|
|
|
|
this.lstProduct.Add(prod);
|
|
|
|
try
|
|
{
|
|
StreamWriter writer1 = new StreamWriter(exportFileName, true, Encoding.GetEncoding("gb2312"));
|
|
object[] objArray2 = new object[15];
|
|
objArray2[1] = "https://haohuo.jinritemai.com/views/product/item2?id=" + prod.Id;
|
|
objArray2[2] = ",";
|
|
objArray2[3] = prod.GoodsName;
|
|
objArray2[4] = ",";
|
|
objArray2[5] = prod.Price;
|
|
objArray2[6] = ",";
|
|
objArray2[7] = prod.Sales;
|
|
objArray2[8] = ",";
|
|
objArray2[9] = prod.CommentsCount;
|
|
objArray2[10] = ",";
|
|
objArray2[11] = prod.CommentsRate;
|
|
writer1.WriteLine(string.Concat(objArray2));
|
|
writer1.Close();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
}
|
|
Invoke(new Action(() =>
|
|
{
|
|
var index = this.dgvCollect.Rows.Add(false, prod.Id, prod.GoodsName, null, prod.Price, prod.Sales, prod.CommentsCount,
|
|
prod.CommentsRate, "删除");
|
|
}));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Invoke(new Action(() =>
|
|
{
|
|
btnCollect.Text = "开始采集";
|
|
this.statusBar.lblTaskStatus.Text = "采集结束,共采集到商品" + this.lstProduct.Count + "个";
|
|
this.statusBar.pgbTaskProgress.Value = n;
|
|
this.statusBar.pgbTaskProgress.Text = n + "/" + total;
|
|
this.statusBar.pgbTaskProgress.Maximum = total;
|
|
}));
|
|
}, cancellationTokenSource.Token);
|
|
}
|
|
}
|
|
|
|
private string CollectCaiNiXiHuan(string cookies, string productId, string pageNum = "1", string cursor = "20")
|
|
{
|
|
HttpWebResponse response = null;
|
|
string result;
|
|
try
|
|
{
|
|
string url = "https://api5-normal-c-lf.amemv.com/aweme/v2/commerce/favorite/feed?app_name=aweme&channel=App%20Store&slide_guide_has_shown=1&minor_status=0&product_id=" +
|
|
productId + "&page_num=" + pageNum + "&cursor=" + cursor + "&page_name=product_detail&feedbacks=&count=20&filters=&filter_type=";
|
|
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
|
|
|
|
request.ContentType = "application/x-www-form-urlencoded";
|
|
request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36";
|
|
request.Headers.Set(HttpRequestHeader.Cookie, cookies);
|
|
|
|
response = (HttpWebResponse)request.GetResponse();
|
|
}
|
|
catch (WebException ex)
|
|
{
|
|
if (ex.Status == WebExceptionStatus.ProtocolError)
|
|
{
|
|
response = (HttpWebResponse)ex.Response;
|
|
result = GetProxyHtml.ReadResponse(response);
|
|
if (response != null) response.Close();
|
|
return result;
|
|
}
|
|
else return ex.Message;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
if (response != null) response.Close();
|
|
return e.Message;
|
|
}
|
|
result = GetProxyHtml.ReadResponse(response);
|
|
if (response != null) response.Close();
|
|
return result;
|
|
}
|
|
|
|
public static string GetComments(string cookies, string productId)
|
|
{
|
|
HttpWebResponse response = null;
|
|
string result;
|
|
try
|
|
{
|
|
string url = "http://lianmengapi.snssdk.com/ies/v2/decision/getProductComments?product_id=" + productId + "&aid=1128";
|
|
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
|
|
|
|
request.ContentType = "application/x-www-form-urlencoded";
|
|
request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36 Edg/91.0.864.177";
|
|
request.Headers.Set(HttpRequestHeader.Cookie, cookies);
|
|
|
|
response = (HttpWebResponse)request.GetResponse();
|
|
}
|
|
catch (WebException ex)
|
|
{
|
|
if (ex.Status == WebExceptionStatus.ProtocolError)
|
|
{
|
|
response = (HttpWebResponse)ex.Response;
|
|
result = GetProxyHtml.ReadResponse(response);
|
|
if (response != null) response.Close();
|
|
return result;
|
|
}
|
|
else return ex.Message;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
if (response != null) response.Close();
|
|
return e.Message;
|
|
}
|
|
result = GetProxyHtml.ReadResponse(response);
|
|
if (response != null) response.Close();
|
|
return result;
|
|
}
|
|
|
|
private void btnLoginDouyin_Click(object sender, EventArgs e)
|
|
{
|
|
DouUserLoginForm dForm = new DouUserLoginForm();
|
|
dForm.ShowDialog();
|
|
}
|
|
|
|
private void btnExport_Click(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
SaveFileDialog saveFileDialog1 = new SaveFileDialog();
|
|
saveFileDialog1.Filter = "表格文件(*.csv)|*.csv";
|
|
saveFileDialog1.FileName = "猜你喜欢采集" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".csv";
|
|
saveFileDialog1.FilterIndex = 2;
|
|
saveFileDialog1.RestoreDirectory = true;
|
|
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
|
|
{
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.AppendLine("商品ID," + "商品名称," + "价格," + "销量," + "评论数," + "好评率");
|
|
foreach (var goodsInfo in lstProduct)
|
|
{
|
|
sb.AppendLine("https://haohuo.jinritemai.com/views/product/item2?id=" + goodsInfo.Id + "," + goodsInfo.GoodsName + ","
|
|
+ goodsInfo.Price + "," + goodsInfo.Sales + "," + goodsInfo.CommentsCount + "," + goodsInfo.CommentsRate);
|
|
}
|
|
System.IO.File.WriteAllText(saveFileDialog1.FileName, sb.ToString(), Encoding.Default);
|
|
BaseForms.BaseMsgForm.ShowInfo("导出成功");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
BaseForms.BaseMsgForm.ShowError(ex.Message);
|
|
}
|
|
}
|
|
|
|
private void dgvCollect_CellContentClick(object sender, DataGridViewCellEventArgs e)
|
|
{
|
|
if (e.RowIndex < 0 || e.ColumnIndex < 0)
|
|
return;
|
|
|
|
var goodsId = dgvCollect.Rows[e.RowIndex].Cells["colProductId"].Value.ToString();
|
|
var columnName = dgvCollect.Columns[e.ColumnIndex].Name;
|
|
if (columnName == "colProductName")
|
|
{
|
|
string url = "https://haohuo.jinritemai.com/views/product/item2?id=" + goodsId;
|
|
GetHtml.OpenUrl(url);
|
|
}
|
|
}
|
|
}
|
|
}
|