328 lines
16 KiB
C#
328 lines
16 KiB
C#
using AllBase;
|
|
using AllBase.Helper;
|
|
using AllBase.Model.Result;
|
|
using LittleRabbit.LittleRabbitForms.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 LittleRabbit.LittleRabbitForms.CollectForms
|
|
{
|
|
public partial class KeywordCollectForm : Form
|
|
{
|
|
List<DouGoodsCollectInfo> lstProduct = new List<DouGoodsCollectInfo>();
|
|
CancellationTokenSource cancellationTokenSource = null;
|
|
decimal priceMin = 0;
|
|
decimal priceMax = 99999999;
|
|
long salesMin = 0;
|
|
long salesMax = 99999999;
|
|
decimal yongjinMin = 0;
|
|
decimal yongjinMax = 99999999;
|
|
decimal scoreMin = 0;
|
|
decimal scoreMax = 5;
|
|
long commentCountMin = 0;
|
|
long commentCountMax = 99999999;
|
|
decimal commentRateMin = 0;
|
|
decimal commentRateMax = 100;
|
|
|
|
public KeywordCollectForm()
|
|
{
|
|
InitializeComponent();
|
|
|
|
}
|
|
|
|
|
|
private string Collect(string cookies, string collectKeyword, string pageNum = "1", string sortText = "", string sortId = "0")
|
|
{
|
|
HttpWebResponse response = null;
|
|
string result;
|
|
try
|
|
{
|
|
string url = "https://lianmengapi.snssdk.com/selection_api/search/pmt?app_name=aweme&channel=App%20Store" +
|
|
"&slide_guide_has_shown=1&minor_status=0&cursor=" + (pageNum.ParseToInt() * 20 - 20) + "&count=20" +
|
|
"&search_text=" + AllBase.HttpUtility.UrlEncode(collectKeyword, Encoding.UTF8) + "&request_tag_from=m" +
|
|
"&aid=1128&order_by=" + sortText + "&sort=" + sortId;
|
|
url = "https://buyin.jinritemai.com/pc/selection/search/pmt?page=" + pageNum
|
|
+ "&page_size=20&search_text=" + HttpUtility.UrlEncode(collectKeyword, Encoding.UTF8)
|
|
+ "&order_by=" + sortText + "&sort=" + sortId;
|
|
|
|
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
|
|
|
|
request.ContentType = "application/x-www-form-urlencoded";
|
|
//request.Headers.Set(HttpRequestHeader.Cookie, @"sid_tt=e21290832ad2b7efaeceb9cdc6c20935");
|
|
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 btnCollect_Click(object sender, EventArgs e)
|
|
{
|
|
if (this.btnCollect.Text == "停止采集")
|
|
{
|
|
cancellationTokenSource.Cancel();
|
|
return;
|
|
}
|
|
|
|
var cookieShop = GlobalConfig.DouShopLoginList.FirstOrDefault(s => s.LoginStatus == "登录成功");
|
|
if (cookieShop == null)
|
|
{
|
|
BaseForms.BaseMsgForm.ShowError("请登录店铺账号后搜索");
|
|
return;
|
|
}
|
|
|
|
priceMin = this.txtPriceMin.Text.ParseToDecimal();
|
|
priceMax = this.txtPriceMax.Text.ParseToDecimal();
|
|
salesMin = this.txtSellCountMin.Text.ParseToLong();
|
|
salesMax = this.txtSellCountMax.Text.ParseToLong();
|
|
yongjinMin = this.txtYongJinMin.Text.ParseToDecimal();
|
|
yongjinMax = this.txtYongJinMax.Text.ParseToDecimal();
|
|
scoreMin = this.txtScoreMin.Text.ParseToDecimal();
|
|
scoreMax = this.txtScoreMax.Text.ParseToDecimal();
|
|
commentCountMin = this.txtCommentCountMin.Text.ParseToLong();
|
|
commentCountMax = this.txtCommentCountMax.Text.ParseToLong();
|
|
commentRateMin = this.txtCommentRateMin.Text.ParseToDecimal();
|
|
commentRateMax = this.txtCommentRateMax.Text.ParseToDecimal();
|
|
var totalPage = this.txtTotalPage.Text.ParseToInt();
|
|
|
|
var keywords = this.txtKeyWords.Text.Split(new string[] { "\r", "\n", " ", "," }, StringSplitOptions.RemoveEmptyEntries);
|
|
string sortText = "";
|
|
string sort = "0";
|
|
if (this.cmbCategory.SelectedItem.ToString() == "佣金排序")
|
|
{
|
|
sortText = "cos_ratio";
|
|
sort = "2";
|
|
}
|
|
else if (this.cmbCategory.SelectedItem.ToString() == "销量排序")
|
|
{
|
|
sortText = "sales";
|
|
sort = "2";
|
|
}
|
|
else if (this.cmbCategory.SelectedItem.ToString() == "价格降序")
|
|
{
|
|
sortText = "price";
|
|
sort = "2";
|
|
}
|
|
else if (this.cmbCategory.SelectedItem.ToString() == "价格升序")
|
|
{
|
|
sortText = "price";
|
|
sort = "1";
|
|
}
|
|
lstProduct.Clear();
|
|
this.dgvCollect.Rows.Clear();
|
|
cancellationTokenSource = new CancellationTokenSource();
|
|
btnCollect.Text = "停止采集";
|
|
|
|
int n = 0;
|
|
int total = totalPage * keywords.Count();
|
|
this.statusBar.lblTaskStatus.Text = "开始采集...";
|
|
this.statusBar.pgbTaskProgress.Value = n;
|
|
this.statusBar.pgbTaskProgress.Text = n + "/" + total;
|
|
this.statusBar.pgbTaskProgress.Maximum = total;
|
|
|
|
Task.Run(() =>
|
|
{
|
|
var exportFileName = "采集导出\\爆款关键词采集" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".csv"; try
|
|
{
|
|
if (!Directory.Exists("采集导出"))
|
|
Directory.CreateDirectory("采集导出");
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.AppendLine("关键词,商品ID,商品标题,价格,销量,佣金,佣金率,评论数,好评率,体验分数,店铺名称");
|
|
File.AppendAllText(exportFileName, sb.ToString(), Encoding.Default);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
};
|
|
|
|
foreach (var keyword in keywords)
|
|
{
|
|
for (int i = 0; i < totalPage; i++)
|
|
{
|
|
if (cancellationTokenSource.IsCancellationRequested)
|
|
break;
|
|
|
|
n++;
|
|
int page = i + 1;
|
|
Invoke(new Action(() =>
|
|
{
|
|
this.statusBar.lblTaskStatus.Text = "正在采集关键词:\"" + keyword + "\",当前采集到第 " + page + " 页";
|
|
this.statusBar.pgbTaskProgress.Value = n;
|
|
this.statusBar.pgbTaskProgress.Text = n + "/" + total;
|
|
this.statusBar.pgbTaskProgress.Maximum = total;
|
|
}));
|
|
|
|
var listCollectResult = Collect(GlobalConfig.DouBuyinCookies, keyword, page.ToString(), sortText, sort);
|
|
if (listCollectResult.Contains("用户未登录") || listCollectResult.Contains("当前网络不稳定") || listCollectResult.Contains("操作异常"))
|
|
{
|
|
Invoke(new Action(() =>
|
|
{
|
|
DouUserLoginForm douLoginForm = new DouUserLoginForm("https://buyin.jinritemai.com/mpa/account/login?log_out=1&type=24");
|
|
//DouUserLoginForm douLoginForm = new DouUserLoginForm("https://buyin.jinritemai.com/dashboard/servicehall/daren-square");
|
|
douLoginForm.ShowDialog();
|
|
}));
|
|
cancellationTokenSource.Cancel();
|
|
break;
|
|
}
|
|
|
|
Thread.Sleep(Randomx.GetId(1000, 3000));
|
|
|
|
if (listCollectResult.Contains("\"code\":0"))
|
|
{
|
|
|
|
// todo
|
|
|
|
JObject jObj = JObject.Parse(listCollectResult);
|
|
if (jObj["data"] != null && jObj["data"]["promotions"] != null)
|
|
{
|
|
foreach (JObject obj in jObj["data"]["promotions"])
|
|
{
|
|
DouGoodsCollectInfo goodsInfo = new DouGoodsCollectInfo();
|
|
string goodStr = JsonHelper.SerializeObject(obj);
|
|
goodsInfo.Keyword = keyword;
|
|
goodsInfo.GoodsName = BaseRegex.GetStringJson(ref goodStr, "title");
|
|
goodsInfo.Id = BaseRegex.GetStringJson(ref goodStr, "product_id");
|
|
goodsInfo.Price = (BaseRegex.GetDecimalJson(ref goodStr, "price") / 100).ToString();
|
|
goodsInfo.yj = (BaseRegex.GetDecimalJson(ref goodStr, "cos_fee") / 100).ToString();
|
|
goodsInfo.yjl = (BaseRegex.GetDecimalJson(ref goodStr, "cos_ratio") / 100).ToString();
|
|
goodsInfo.Sales = BaseRegex.GetStringJson(ref goodStr, "month_sales"); // 月销量
|
|
goodsInfo.ShopId = BaseRegex.GetStringJson(ref goodStr, "shop_id");
|
|
goodsInfo.ShopName = BaseRegex.GetStringJson(ref goodStr, "shop_name");
|
|
goodsInfo.Score = BaseRegex.GetDecimalJson(ref goodStr, "exp_score").ParseToDouble();
|
|
|
|
if (goodsInfo.Price.ParseToDecimal() < priceMin || goodsInfo.Price.ParseToDecimal() > priceMax)
|
|
continue;
|
|
if (goodsInfo.yj.ParseToDecimal() < yongjinMin || goodsInfo.yj.ParseToDecimal() > yongjinMax)
|
|
continue;
|
|
if (goodsInfo.Sales.ParseToDecimal() < salesMin || goodsInfo.Sales.ParseToDecimal() > salesMax)
|
|
continue;
|
|
if (goodsInfo.Score.ParseToDecimal() < scoreMin || goodsInfo.Score.ParseToDecimal() > scoreMax)
|
|
continue;
|
|
|
|
var commentResult = CaiNiXiHuanCollectForm.GetComments(GlobalConfig.DouBuyinCookies, goodsInfo.Id);
|
|
|
|
Thread.Sleep(Randomx.GetId(400, 600));
|
|
if (!string.IsNullOrEmpty(commentResult) && commentResult.Contains("\"status_code\":0"))
|
|
{
|
|
goodsInfo.CommentsCount = BaseRegex.GetIntJson(ref commentResult, "total_comments_num");
|
|
goodsInfo.CommentsRate = BaseRegex.GetDecimalJson(ref commentResult, "good_comment_ratio").ParseToDouble() / 100;
|
|
}
|
|
|
|
// 筛选条件
|
|
if (goodsInfo.CommentsRate < this.commentRateMin.ParseToDouble() || goodsInfo.CommentsRate > this.commentRateMax.ParseToDouble()
|
|
|| goodsInfo.CommentsCount < this.commentCountMin || goodsInfo.CommentsCount > this.commentCountMax)
|
|
continue;
|
|
|
|
Invoke(new Action(() =>
|
|
{
|
|
this.dgvCollect.Rows.Add(false, keyword, goodsInfo.Id, goodsInfo.GoodsName, goodsInfo.Price, goodsInfo.Sales, goodsInfo.yj, goodsInfo.yjl,
|
|
goodsInfo.CommentsCount, goodsInfo.CommentsRate, goodsInfo.Score, goodsInfo.ShopName);
|
|
|
|
}));
|
|
try
|
|
{
|
|
lstProduct.Add(goodsInfo);
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.AppendLine(goodsInfo.Keyword + ",https://haohuo.jinritemai.com/views/product/item2?id=" + goodsInfo.Id + "," + goodsInfo.GoodsName + ","
|
|
+ goodsInfo.Price + "," + goodsInfo.Sales + "," + goodsInfo.yj + "," + goodsInfo.yjl + "," + goodsInfo.CommentsCount + ","
|
|
+ goodsInfo.CommentsRate + "," + goodsInfo.Score + "," + goodsInfo.ShopName);
|
|
System.IO.File.WriteAllText(exportFileName, sb.ToString(), Encoding.Default);
|
|
}
|
|
catch (Exception ex) { }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
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 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(goodsInfo.Keyword + ",https://haohuo.jinritemai.com/views/product/item2?id=" + goodsInfo.Id + "," + goodsInfo.GoodsName + ","
|
|
+ goodsInfo.Price + "," + goodsInfo.Sales + "," + goodsInfo.yj + "," + goodsInfo.yjl + "," + goodsInfo.CommentsCount + ","
|
|
+ goodsInfo.CommentsRate + "," + goodsInfo.Score + "," + goodsInfo.ShopName);
|
|
}
|
|
System.IO.File.WriteAllText(saveFileDialog1.FileName, sb.ToString(), Encoding.Default);
|
|
BaseForms.BaseMsgForm.ShowInfo("导出成功");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
BaseForms.BaseMsgForm.ShowError(ex.Message);
|
|
}
|
|
}
|
|
|
|
private void KeywordCollectForm_Load(object sender, EventArgs e)
|
|
{
|
|
this.cmbCategory.SelectedIndex = 0;
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|