第二篇:速卖通产品采集系列 之 产品采集实战

上一篇,对速卖通产品采集做了分析,包含要采集产品信息,以及如何采集这些产品信息,这一篇接着来采集实战,相关技术前篇也说过了,不废话直接开项目做。

一, 创建解决方案,编写采集代码

1. 创建解决方案“CollectorSolution”,在其中新建“Collector” 空 ASP.NET MVC 项目,解决方案结构图如下:

2.在“Collector” 项目中,分别新增“CollectingController” 控制器,以及和控制器相关的视图,并将原来默认路由 Home -》 Index 改成 Collecting -》 Index,截图如下:

RouteConfig 修改成如下:

 1 using System.Web.Mvc;
 2 using System.Web.Routing;
 3
 4 namespace Collector
 5 {
 6     public class RouteConfig
 7     {
 8         public static void RegisterRoutes(RouteCollection routes)
 9         {
10             routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
11
12             routes.MapRoute(
13                 name: "Default",
14                 url: "{controller}/{action}/{id}",
15                 defaults: new { controller = "Collecting", action = "Index", id = UrlParameter.Optional }
16             );
17         }
18     }
19 }

3. 分别新增“CollectionViewModel” ,"CollectedProductViewModel","CollectedProductImageViewModel" 视图模型,和一个存放正则表达式的结构体:“ParseProductPatterns”,代码分别如下

1.> CollectionViewModel

 1 using System.Collections.Generic;
 2
 3 namespace Collector.Models
 4 {
 5     public class CollectionViewModel
 6     {
 7         public CollectionViewModel()
 8         {
 9             ProductViews = new List<CollectedProductViewModel>();
10         }
11         public string CollectionUrl { get; set; }
12         public IEnumerable<CollectedProductViewModel> ProductViews { get; set; }
13     }
14 }

2.> CollectedProductViewModel

 1 using System.Collections.Generic;
 2
 3 namespace Collector.Models
 4 {
 5     public class CollectedProductViewModel
 6     {
 7         public CollectedProductViewModel()
 8         {
 9             ProductImages = new List<CollectedProductImageViewModel>();
10         }
11         public string ProductName { get; set; }
12         public decimal ProductPrice { get; set; }
13         public decimal ProductDiscountPrice { get; set; }
14         public string ProductCurrency { get; set; }
15         public string ProductColor { get; set; }
16         public string ProductSize { get; set; }
17         public IEnumerable<CollectedProductImageViewModel> ProductImages { get; set; }
18     }
19 }

3.>CollectedProductImageViewModel

1 namespace Collector.Models
2 {
3     public class CollectedProductImageViewModel
4     {
5         public string ImageUrl { get; set; }
6         public int Sort { get; set; }
7     }
8 }

4.>ParseProductPatterns

namespace Collector.Models
{
    public struct ParseProductPatterns
    {
        public static string ProductNamePattern = "(?<=<h1 class=\"product-name\" itemprop=\"name\">).*?(?=</h1>)";
        public static string ProductJsnPattern = @"(?<=var skuProducts=).*?(?=;\s*var skuAttrIds=)";
        public static string ProductImageJsonPattern = "(?<=window.runParams.imageBigViewURL=).*?(?=;)";
        public static string ProductCurrencyPattern = "(?<=window.runParams.currencyCode=\").*?(?=\";)";
        public static string ProductColorPattern =
            "(?<=<a data-role=\"sku\" data-sku-id=\"{0}\" id=\"sku-1-{0}\" title=\").*?(?=\")";
        public static string ProductSizePattern =
            "(?<=<a data-role=\"sku\" data-sku-id=\"{0}\" id=\"sku-2-{0}\" href=\"javascript:void\\(0\\)\"\\s+><span>).*?(?=</)";
    }
}

基本上容易理解,我这里就不再一一讲解了。

4. 视图布局设计很简单,如下图

采集地址 就是速卖通产品地址,这里不支持店铺和类型采集地址。表格就是采集产品信息展示。

5. 控制器和视图代码如下

1.> CollectingController

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text.RegularExpressions;
  5 using System.Web.Mvc;
  6 using Collector.Models;
  7 using Newtonsoft.Json.Linq;
  8 using RestSharp;
  9
 10 namespace Collector.Controllers
 11 {
 12     public class CollectingController : Controller
 13     {
 14         // GET: Collecting
 15         public ActionResult Index()
 16         {
 17             return View();
 18         }
 19
 20         [HttpPost]
 21         public ActionResult Index(CollectionViewModel collectionView)
 22         {
 23             collectionView = ColllectWithParse(collectionView);
 24             return View(collectionView);
 25         }
 26
 27         public CollectionViewModel ColllectWithParse(CollectionViewModel collectionView)
 28         {
 29             if (collectionView == null || string.IsNullOrEmpty(collectionView.CollectionUrl))
 30             {
 31                 return collectionView;
 32             }
 33             var client = new RestClient(collectionView.CollectionUrl);
 34             var request = new RestRequest(Method.GET);
 35             var response = client.Execute(request);
 36             var htmlContent = response.Content;
 37             collectionView.ProductViews = ParseProducts(htmlContent);
 38             return collectionView;
 39         }
 40
 41         public IEnumerable<CollectedProductViewModel> ParseProducts(string productHtmlContent)
 42         {
 43             var productName = RegexMatchValue(ParseProductPatterns.ProductNamePattern, productHtmlContent);
 44             var productCuurency = RegexMatchValue(ParseProductPatterns.ProductCurrencyPattern, productHtmlContent);
 45
 46             var productJson = RegexMatchValue(ParseProductPatterns.ProductJsnPattern, productHtmlContent);
 47
 48             var prodctJsonArray = JArray.Parse(productJson);
 49             var products =
 50                 prodctJsonArray.Select(pja =>
 51                 {
 52                     var colorWithSizeCode = pja["skuPropIds"].ToString().Split(‘,‘);
 53                     var priceJson = pja["skuVal"];
 54                     var skuPrice = priceJson["skuPrice"];
 55                     var price = skuPrice == null ? "0" : skuPrice.ToString();
 56                     var actSkuPrice = priceJson["actSkuPrice"];
 57                     var discountPrice = actSkuPrice == null ? "0" : actSkuPrice.ToString();
 58                     return new
 59                     {
 60                         ColorCode = colorWithSizeCode.First(),
 61                         SizeCode = colorWithSizeCode.Last(),
 62                         Price = Convert.ToDecimal(price),
 63                         DiscountPrice = Convert.ToDecimal(discountPrice),
 64                     };
 65                 }).ToList();
 66
 67             var collectedImages = ParseProducImages(productHtmlContent);
 68
 69             var collectedProducts = products.Select(p => new CollectedProductViewModel
 70             {
 71                 ProductName = productName,
 72                 ProductPrice = p.Price,
 73                 ProductDiscountPrice = p.DiscountPrice,
 74                 ProductCurrency = productCuurency,
 75                 ProductColor = SetProductColorWithSize(ParseProductPatterns.ProductColorPattern,p.ColorCode,productHtmlContent),
 76                 ProductSize = SetProductColorWithSize(ParseProductPatterns.ProductSizePattern, p.SizeCode, productHtmlContent),
 77                 ProductImages = collectedImages
 78             }).ToList();
 79             return collectedProducts;
 80         }
 81
 82         private IEnumerable<CollectedProductImageViewModel> ParseProducImages(string productHtmlContent)
 83         {
 84             var imagesJson = RegexMatchValue(ParseProductPatterns.ProductImageJsonPattern, productHtmlContent);
 85             var imageJsonArray = JArray.Parse(imagesJson);
 86
 87             var images = imageJsonArray.ToObject<List<string>>();
 88             return images.Select((t, i) => new CollectedProductImageViewModel
 89             {
 90                 ImageUrl = t,
 91                 Sort = i
 92             });
 93         }
 94
 95         private string SetProductColorWithSize(string pattern, string colorWithSizeCode,string input)
 96         {
 97             var newPattern = string.Format(pattern, colorWithSizeCode);
 98             return RegexMatchValue(newPattern, input);
 99         }
100
101         private string RegexMatchValue(string pattern, string input, RegexOptions regexOptions = RegexOptions.IgnoreCase|RegexOptions.Singleline)
102         {
103             var regex = new Regex(pattern, regexOptions);
104             var match = regex.Match(input);
105             return match.Value;
106         }
107     }
108 }

2.> Collecting->Index

 1 @model  Collector.Models.CollectionViewModel
 2 <!DOCTYPE html>
 3
 4 <html>
 5 <head>
 6     <meta name="viewport" content="width=device-width" />
 7     <title></title>
 8     <!-- CSS goes in the document HEAD or added to your external stylesheet -->
 9     <style type="text/css">
10         table.gridtable {
11             font-family: verdana,arial,sans-serif;
12             font-size: 11px;
13             color: #333333;
14             border-width: 1px;
15             border-color: #666666;
16             border-collapse: collapse;
17         }
18
19             table.gridtable th {
20                 border-width: 1px;
21                 padding: 8px;
22                 border-style: solid;
23                 border-color: #666666;
24                 background-color: #dedede;
25             }
26
27             table.gridtable td {
28                 border-width: 1px;
29                 padding: 8px;
30                 border-style: solid;
31                 border-color: #666666;
32                 background-color: #ffffff;
33             }
34     </style>
35 </head>
36 <body>
37     <div>
38         @using (Html.BeginForm("Index", "Collecting", FormMethod.Post))
39         {
40             <table>
41                 <tr>
42                     <td>采集地址:</td>
43                     <td>
44                         @Html.TextAreaFor(m => m.CollectionUrl, 4, 0, new { style = "width:1500px;" })
45                     </td>
46
47                 </tr>
48                 <tr><td colspan="2" style="text-align: right;"><input type="submit" value="开始采集" /></td></tr>
49             </table>
50         }
51     </div>
52     <div>
53         <table class="gridtable">
54             <thead>
55                 <tr>
56                     <th width="5%">编号</th>
57                     <th width="5%">图片</th>
58                     <th width="30%">产品名称</th>
59
60                     <th width="10%">产品单价</th>
61                     <th width="10%">产品参考单价</th>
62                     <th width="10%">产品币别</th>
63                     <th width="10%">产品颜色</th>
64                     <th width="10%">产品大小</th>
65                 </tr>
66             </thead>
67             <tbody>
68                 @{
69                     var i = 0;
70                     if (Model == null || Model.ProductViews == null)
71                     {
72                         return;
73                     }
74                 }
75                 @foreach (var collectedProduct in Model.ProductViews)
76                 {
77                     <tr>
78                         <td align="center">@{i++;}@i</td>
79                         <td><img src="@collectedProduct.ProductImages.FirstOrDefault().ImageUrl" width="60" height="60" /></td>
80                         <td>@collectedProduct.ProductName</td>
81                         <td>@collectedProduct.ProductDiscountPrice</td>
82                         <td>@collectedProduct.ProductPrice</td>
83                         <td>@collectedProduct.ProductCurrency</td>
84                         <td>@collectedProduct.ProductColor</td>
85                         <td>@collectedProduct.ProductSize</td>
86                     </tr>
87                 }
88
89             </tbody>
90
91         </table>
92     </div>
93 </body>
94 </html>

这里要说明的是,本篇只是采集的冰山一角的例子,所有没有搞得很复杂,没有严格封装,不管是前端,还是后端,希望大家了解,还有本人不喜好在代码中加注释,在我看来代码就是注释。

二, 测试结果,将MVC项目,部署到IIS,端口号1005,走起看效果。

1. 测试上一篇速卖通产品地址:

http://www.aliexpress.com/store/product/Yoga-Tops-Women-Women-Yoga-Shirts-Womens-Sportswear-Gym-Woman-Running-Shirt-Camisetas-Deporte-Mujer-Gym/1025110_32620359354.html?spm=a2g01.8032156.template-section-container.27.wcM8ES&sdom=3514.555719.493653.0_32620359354

效果截图如下:

刚刚采集发现上一篇写的这个产品地址,速卖通不打折,因此没有了折扣价格。

2.再采集一个地址:

http://www.aliexpress.com/store/product/LEVEL-4-shock-Professional-running-intensive-training-without-rims-snow-sports-bra-open-front-zipper-style/1025110_32357688343.html?spm=2114.12010108.1000013.1.uvJqBj

截图如下

这个产品的产品变体有很多,所有一网页还显示不了。

源码码:https://github.com/haibozhou1011/Collector

总结:

好了,速卖通产品采集系列,就全部结束了,总的来说,采集这个活技术都是大家经常用的,主要是前期分析,抓产品信息规则,每个网站多有规律,大家留心观察就会找到一些蛛丝马迹,就会有所突破。希望大家如果有更好的采集方法,一定要和大家分享。

时间: 2025-01-01 09:26:08

第二篇:速卖通产品采集系列 之 产品采集实战的相关文章

第一篇:速卖通产品采集系列 之 产品采集分析

电商网站产品采集,我相信是一个很需要的功能,主要能够减轻产品编辑和上架所带来一些繁琐的事情,当然除了电商这块,其他方面数据采集也是需要的,比喻新闻类门户等,这系列我们来讲讲如何来采集速卖通产品,主要要说明一下,这里不考虑Ajax,验证码等特殊环境,我们采集速卖通如果不是采集很频繁,就当作为一个良性的采集环境,下面就不太多废话了,直接先分析采集产品信息,包含变体(有Color,Size,且价格不一样,做为多个产品采集下来). 一.采集前技术和相关工具 1. C#正则表达式学习:(正则表达式用来干嘛

速卖通新手快速入门手册之一认识物流

写在帖子之前的话 最近有一大批朋友想做速卖通或者有的刚做速卖通,遇到了不少问题,都来问我,我觉得这个是一个好的趋势,说明跨境电商的市场正在走向成熟,相关配套也会越来越完善.但是也是说明竞争将会前所未有的激烈了. 我很想一个一个的为我的朋友耐心的回答所有问题,但是显然问题太多了,有的甚至是我们从来都没想过的,在边回答边学习的过程中,我想起了自己刚开始摸索速卖通的时候,多希望能有个前辈能解答我的问题,于是我有了一个想法,我要写一些关于速卖通新手会遇到的问题这样一个新手快速入门手册,能让所有有心想要做

速卖通流量入口有哪些,速卖通怎么引流?

有足够多的流量是提升店铺成交量的前提,今天要和大家分享速卖通怎么引流?速卖通站内.站外流量入口有哪些? 一.速卖通站内流量 1.速卖通橱窗推荐 速卖通平台在卖家达到一定等级或者在一些特殊活动中会赠送橱窗位.与线下商店靠近窗户或门口的橱窗位置相似,被橱窗推荐的产品将在同等质量的产品中优先排名,近一步提升曝光.合理利用这一点也能获取不菲的免费流量. 挑选好橱窗产品是关键中的关键,一般可以结合以下几点来挑选橱窗产品:主打产品.热销产品.新出产品.或者结合季节和展会. 需要强调的是,橱窗在速卖通平台的买

速卖通新店运营必看的6个思路

1. 打破原有思路,优化产品结构. 杂货时代已经过去了,再想凭借多发布产品来获取更多流量已经不可能了,比如现在在淘宝上,谁还记得淘宝的第一个金冠店柠檬绿茶呢?所以,在新形势下,一定要做到优化产品结构,重点打造核心产品,而不是盲目铺货,胡乱上新. 2. 提高产品质量,精选高质产品. Ebay已经因为整个平台产品品质不高而开始没落,Amazon则因为产品品质和物流时效得到越来越多的顾客的青睐,速卖通虽然凭着起步时蛮干抢粮的方式,从新兴国家市场拔得头筹,但下一步的发展,对产品品质方面的要求会越来越高,

速卖通 排序规则解析

排序规则解析 一.搜索排序的原则 AliExpress搜索的整体目标是帮助我们的买家快速找到想要的商品并且能够有比较好的采购交易体验,而搜索的排名的目标就是要将最好的商品.服务能力最好的卖家优先推荐给我们的买家,谁能带给买家最好的采购体验,谁的商品就会排序靠前. 在排序过程中,我们将始终坚持公平的原则,对于所有的卖家采取相同的标准,给予表现好的卖家更多的曝光机会,降低表现差的卖家曝光机会甚至没有曝光机会.我们提倡卖家间公平竞争,优胜劣汰,能够提供最好的采购体验给我们的买家,让更多的买家满意愿意来

速卖通---发布商品aeopAeProductPropertys这个字段值报07004013的错误

由于文档的说明很少,导致里面改填写那些值都是靠自己推敲出来,当然可以根据他们的错误提示了研究,他们的错误提示也给出了相关的帮助了, 例如通过categoryid的200000001获取到"id":10,"values":[{"id":200002203,"names":{"zh":"醋酸纤维","en":"Acetate"},"attri

速卖通标题应如何选词,从而提高曝光。麦言站长【罗小迪】 直播

很荣幸邀请到麦言美女站长[罗小迪]进行直播分享~ 直播主题:速卖通标题应如何选词,从而提高曝光量. 直播时间:5月20日星期六晚8点  直播入口(两个途径,大家赶紧报名哈): 1.点击下面网址进入麦言直播入口: https://m.qlchat.com/live/850000023002978.htm 2.各位小伙伴也可以微信扫描下方二维码进入直播学堂报名: 不容错过,敬请期待~

分享下速卖通api的java的入门代码

package com.print.base; import java.io.*; import java.math.BigInteger; import java.net.URL; import java.net.URLEncoder; import java.util.*; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import net.sf.json.JSONArray; import net.sf.j

外贸开发,用java调用速卖通api第一步,token的获取。

第一步 定义速卖通api的常量 public String client_id; public String client_key; public String site; 第二步 获取登陆的uRL /** * getloginurl * @param redirect_uri * @return */ public String GetLoginUrl(String redirect_uri) { String param = (new StringBuilder("client_id=&qu