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 lstProduct = new List(); 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); } } } }