使用 C# 抓取购物网站数据
了解如何使用 C# 和 WebScraper 框架从购物网站中抓取产品类别和项目,将结构化数据从 HTML 元素提取到自定义模型中。 本综合指南将指导您使用 IronWebScraper 库构建一个强大的电子商务刮板。
as-heading:2(快速入门:在 C# 中抓取购物网站)
立即开始使用 NuGet 创建 PDF 文件:
使用 NuGet 包管理器安装 IronWebScraper
复制并运行这段代码。
using IronWebScraper; public class QuickShoppingScraper : WebScraper { public override void Init() { // Apply your license key License.LicenseKey = "YOUR-LICENSE-KEY"; // Set the starting URL this.Request("https://shopping-site.com", Parse); } public override void Parse(Response response) { // Extract product data foreach (var product in response.Css(".product-item")) { var item = new { Name = product.Css(".product-name").First().InnerText, Price = product.Css(".price").First().InnerText, Image = product.Css("img").First().Attributes["src"] }; Scrape(item, "products.jsonl"); } } } // Run the scraper var scraper = new QuickShoppingScraper(); scraper.Start();部署到您的生产环境中进行测试
1.创建一个名为 "ShoppingSiteSample "的新控制台应用程序项目 2.添加一个名为 "ShoppingScraper "的类,该类继承自<代码>WebScraper</代码 3.为 Category 和 Product 数据创建模型 4.重载 Init() 以设置起始 URL 和 Parse() 方法进行刮擦 5.运行 scraper 将类别和产品提取为 JSONL 文件
如何分析购物网站的 HTML 结构? 选择一个购物网站,分析其内容结构。 了解 HTML 结构是成功进行网络刮擦的关键。 在编写任何代码之前,请花时间使用浏览器开发工具分析目标网站的结构。
如图所示,左侧边栏包含网站产品类别的链接。 第一步是调查网站的 HTML 并规划刮擦方法。 这一分析阶段对于制定有效的搜索策略至关重要。为什么理解 HTML 结构很重要? 时尚网站的类别有子类别(男装、女装、儿童)。 了解这种分层结构有助于设计适当的数据模型和搜索逻辑。 在使用 [高级网络搜刮功能](https://ironsoftware.com/csharp/webscraper/tutorials/webscraping-in-c-sharp-advanced/)时,正确的 HTML 分析变得更加重要。 ```html
如何设置网络抓取项目? 按照 [C# Web scraping](https://ironsoftware.com/csharp/webscraper/tutorials/webscraping-in-c-sharp/) 的最佳实践建立一个项目。 1.创建一个新的控制台应用程序,或为名为 "ShoppingSiteSample "的示例添加一个新文件夹 2.添加一个名为 "ShoppingScraper "的新类 3.从搜索网站类别及其子类别开始 4.通过 NuGet 软件包管理器或软件包管理控制台安装 `IronWebScraper` : ```csharp Install-Package IronWebScraper ```分类应使用何种数据模型? 创建一个类别模型,正确表达所发现的层次结构: ```csharp public class Category { ////// Gets or sets the name. /// ////// The name. /// public string Name { get; set; } ////// Gets or sets the URL. /// ////// The URL. /// public string URL { get; set; } ////// Gets or sets the subcategories. /// ////// The subcategories. /// public ListSubCategories { get; set; } // Additional properties for enhanced data collection public int ProductCount { get; set; } public DateTime LastScraped { get; set; } public string CategoryType { get; set; } } ```如何构建基本的 Scraper 逻辑? 构建刮板逻辑,切记在运行刮板之前[应用您的许可证密钥](https://ironsoftware.com/csharp/webscraper/get-started/license-keys/): ```csharp public class ShoppingScraper : WebScraper { ////// Initialize the web scraper, setting the start URLs and allowed/banned domains or URL patterns. /// public override void Init() { // Apply your license key - get one from https://ironsoftware.com/csharp/webscraper/licensing/ License.LicenseKey = "LicenseKey"; this.LoggingLevel = WebScraper.LogLevel.All; this.WorkingDirectory = AppSetting.GetAppRoot() + @"\ShoppingSiteSample\Output\"; // Configure request settings for better performance this.Request("www.webSite.com", Parse); } ////// Parses the HTML document of the response to scrap the necessary data. /// ///The HTTP Response object to parse.public override void Parse(Response response) { var categoryList = new List(); // Iterate through each link in the menu and extract the category data. foreach (var Links in response.Css("#menuFixed > ul > li > a")) { var cat = new Category { URL = Links.Attributes["href"], Name = Links.InnerText, LastScraped = DateTime.Now }; categoryList.Add(cat); } // Save the scraped data into a JSONL file. Scrape(categoryList, "Shopping.jsonl"); } } ```菜单中的目标元素是什么? 从菜单中抓取链接需要精确的 CSS 选择器。 [API 参考](https://ironsoftware.com/csharp/webscraper/object-reference/api/)提供了有关可用选择器方法的详细信息:
如何同时抓取主分类和子分类? 更新代码以抓取主要类别和所有子链接。 这种方法可确保完整的导航结构捕获: ```csharp public override void Parse(Response response) { // List of Category Links (Root) var categoryList = new List(); // Traverse each 'li' under the fixed menu foreach (var li in response.Css("#menuFixed > ul > li")) { // List of Main Links foreach (var Links in li.Css("a")) { var cat = new Category { URL = Links.Attributes["href"], Name = Links.InnerText, SubCategories = new List(), LastScraped = DateTime.Now }; // List of Subcategories Links foreach (var subCategory in li.Css("a[class=subcategory]")) { var subcat = new Category { URL = subCategory.Attributes["href"], Name = subCategory.InnerText, CategoryType = "Subcategory" }; // Check if subcategory link already exists if (cat.SubCategories.Find(c => c.Name == subcat.Name && c.URL == subcat.URL) == null) { // Add sublinks cat.SubCategories.Add(subcat); } } // Update product count based on subcategories cat.ProductCount = cat.SubCategories.Count; // Add Main Category to the list categoryList.Add(cat); } } // Save the scraped data into a JSONL file. Scrape(categoryList, "Shopping.jsonl"); } ```如何从分类页面中提取产品信息? 有了所有网站类别的链接,就可以开始搜索每个类别中的产品。 在处理产品页面时,[线程安全](https://ironsoftware.com/csharp/webscraper/troubleshooting/thread-safety/)对于优化性能非常重要。 导航至任何类别并检查内容:
产品的 HTML 结构是什么样的? 检查 HTML 结构以了解产品组织: ```html ```我应该创建哪种产品模型? 为该内容建立产品模型。 在使用[购物网站搜索](https://ironsoftware.com/csharp/webscraper/how-to/scraping-from-a-shopping-website/)时,请捕捉所有相关的产品详细信息: ```csharp public class Product { ////// Gets or sets the name. /// ////// The name. /// public string Name { get; set; } ////// Gets or sets the price. /// ////// The price. /// public string Price { get; set; } ////// Gets or sets the image. /// ////// The image. /// public string Image { get; set; } // Additional properties for comprehensive data collection public string Brand { get; set; } public string OldPrice { get; set; } public string Discount { get; set; } public float Rating { get; set; } public int ReviewCount { get; set; } public ListAvailableSizes { get; set; } public string ProductUrl { get; set; } public string SKU { get; set; } public DateTime ScrapedDate { get; set; } } ```如何添加产品抓取功能? 要抓取分类页面,请添加一个新的抓取方法,该方法具有错误处理和数据验证功能: ```csharp public void ParseCategory(Response response) { // List of Products var productList = new List(); // Iterate through product links in the product section foreach (var Links in response.Css("section.products > div > a")) { try { var product = new Product { Name = Links.Css("h2.title > span.name").First().InnerText, Brand = Links.Css("h2.title > span.brand").FirstOrDefault()?.InnerText ?? "Unknown", Price = Links.Css("div.price-container > span.price-box > span.price > span[data-price]").First().InnerText, Image = Links.Css("div.image-wrapper.default-state > img").First().Attributes["src"], ProductUrl = Links.Attributes["href"], SKU = Links.ParentNode.Attributes["data-sku"], ScrapedDate = DateTime.Now }; // Extract old price if available var oldPriceElement = Links.Css("span.price.-old > span[data-price]").FirstOrDefault(); if (oldPriceElement != null) { product.OldPrice = oldPriceElement.InnerText; } // Extract discount percentage var discountElement = Links.Css("span.sale-flag-percent").FirstOrDefault(); if (discountElement != null) { product.Discount = discountElement.InnerText; } // Extract rating information var ratingWidth = Links.Css("div.stars").FirstOrDefault()?.Attributes["style"]; if (!string.IsNullOrEmpty(ratingWidth)) { var width = System.Text.RegularExpressions.Regex.Match(ratingWidth, @"(\d+)%").Groups[1].Value; if (int.TryParse(width, out int ratingPercent)) { product.Rating = ratingPercent / 20.0f; // Convert percentage to 5-star scale } } // Extract review count var reviewText = Links.Css("div.total-ratings").FirstOrDefault()?.InnerText; if (!string.IsNullOrEmpty(reviewText)) { var reviewCount = System.Text.RegularExpressions.Regex.Match(reviewText, @"\d+").Value; if (int.TryParse(reviewCount, out int count)) { product.ReviewCount = count; } } // Extract available sizes product.AvailableSizes = Links.Css("div.list.-sizes > span.sku-size") .Select(s => s.InnerText) .ToList(); productList.Add(product); } catch (Exception ex) { // Log error and continue with next product Console.WriteLine($"Error parsing product: {ex.Message}"); } } // Save the scraped product data into a JSONL file. Scrape(productList, "Products.jsonl"); // Handle pagination if needed var nextPageLink = response.Css("a.pagination-next").FirstOrDefault(); if (nextPageLink != null) { var nextPageUrl = nextPageLink.Attributes["href"]; this.Request(nextPageUrl, ParseCategory); } } ``` 这种刮擦购物网站的综合方法可确保捕获所有相关产品信息,同时优雅地处理错误。 对于更高级的应用场景,请探索 [](https://ironsoftware.com/csharp/webscraper/tutorials/webscraping-in-c-sharp-advanced/)`IronWebScraper`中提供的高级 Web scraping 功能。
如何构建基本的 Scraper 逻辑? 构建刮板逻辑,切记在运行刮板之前[应用您的许可证密钥](https://ironsoftware.com/csharp/webscraper/get-started/license-keys/): ```csharp public class ShoppingScraper : WebScraper { ////// Initialize the web scraper, setting the start URLs and allowed/banned domains or URL patterns. /// public override void Init() { // Apply your license key - get one from https://ironsoftware.com/csharp/webscraper/licensing/ License.LicenseKey = "LicenseKey"; this.LoggingLevel = WebScraper.LogLevel.All; this.WorkingDirectory = AppSetting.GetAppRoot() + @"\ShoppingSiteSample\Output\"; // Configure request settings for better performance this.Request("www.webSite.com", Parse); } ////// Parses the HTML document of the response to scrap the necessary data. /// ///The HTTP Response object to parse.public override void Parse(Response response) { var categoryList = new List(); // Iterate through each link in the menu and extract the category data. foreach (var Links in response.Css("#menuFixed > ul > li > a")) { var cat = new Category { URL = Links.Attributes["href"], Name = Links.InnerText, LastScraped = DateTime.Now }; categoryList.Add(cat); } // Save the scraped data into a JSONL file. Scrape(categoryList, "Shopping.jsonl"); } } ```菜单中的目标元素是什么? 从菜单中抓取链接需要精确的 CSS 选择器。 [API 参考](https://ironsoftware.com/csharp/webscraper/object-reference/api/)提供了有关可用选择器方法的详细信息:
如何同时抓取主分类和子分类? 更新代码以抓取主要类别和所有子链接。 这种方法可确保完整的导航结构捕获: ```csharp public override void Parse(Response response) { // List of Category Links (Root) var categoryList = new List(); // Traverse each 'li' under the fixed menu foreach (var li in response.Css("#menuFixed > ul > li")) { // List of Main Links foreach (var Links in li.Css("a")) { var cat = new Category { URL = Links.Attributes["href"], Name = Links.InnerText, SubCategories = new List(), LastScraped = DateTime.Now }; // List of Subcategories Links foreach (var subCategory in li.Css("a[class=subcategory]")) { var subcat = new Category { URL = subCategory.Attributes["href"], Name = subCategory.InnerText, CategoryType = "Subcategory" }; // Check if subcategory link already exists if (cat.SubCategories.Find(c => c.Name == subcat.Name && c.URL == subcat.URL) == null) { // Add sublinks cat.SubCategories.Add(subcat); } } // Update product count based on subcategories cat.ProductCount = cat.SubCategories.Count; // Add Main Category to the list categoryList.Add(cat); } } // Save the scraped data into a JSONL file. Scrape(categoryList, "Shopping.jsonl"); } ```如何从分类页面中提取产品信息? 有了所有网站类别的链接,就可以开始搜索每个类别中的产品。 在处理产品页面时,[线程安全](https://ironsoftware.com/csharp/webscraper/troubleshooting/thread-safety/)对于优化性能非常重要。 导航至任何类别并检查内容:
产品的 HTML 结构是什么样的? 检查 HTML 结构以了解产品组织: ```html ```我应该创建哪种产品模型? 为该内容建立产品模型。 在使用[购物网站搜索](https://ironsoftware.com/csharp/webscraper/how-to/scraping-from-a-shopping-website/)时,请捕捉所有相关的产品详细信息: ```csharp public class Product { ////// Gets or sets the name. /// ////// The name. /// public string Name { get; set; } ////// Gets or sets the price. /// ////// The price. /// public string Price { get; set; } ////// Gets or sets the image. /// ////// The image. /// public string Image { get; set; } // Additional properties for comprehensive data collection public string Brand { get; set; } public string OldPrice { get; set; } public string Discount { get; set; } public float Rating { get; set; } public int ReviewCount { get; set; } public ListAvailableSizes { get; set; } public string ProductUrl { get; set; } public string SKU { get; set; } public DateTime ScrapedDate { get; set; } } ```如何添加产品抓取功能? 要抓取分类页面,请添加一个新的抓取方法,该方法具有错误处理和数据验证功能: ```csharp public void ParseCategory(Response response) { // List of Products var productList = new List(); // Iterate through product links in the product section foreach (var Links in response.Css("section.products > div > a")) { try { var product = new Product { Name = Links.Css("h2.title > span.name").First().InnerText, Brand = Links.Css("h2.title > span.brand").FirstOrDefault()?.InnerText ?? "Unknown", Price = Links.Css("div.price-container > span.price-box > span.price > span[data-price]").First().InnerText, Image = Links.Css("div.image-wrapper.default-state > img").First().Attributes["src"], ProductUrl = Links.Attributes["href"], SKU = Links.ParentNode.Attributes["data-sku"], ScrapedDate = DateTime.Now }; // Extract old price if available var oldPriceElement = Links.Css("span.price.-old > span[data-price]").FirstOrDefault(); if (oldPriceElement != null) { product.OldPrice = oldPriceElement.InnerText; } // Extract discount percentage var discountElement = Links.Css("span.sale-flag-percent").FirstOrDefault(); if (discountElement != null) { product.Discount = discountElement.InnerText; } // Extract rating information var ratingWidth = Links.Css("div.stars").FirstOrDefault()?.Attributes["style"]; if (!string.IsNullOrEmpty(ratingWidth)) { var width = System.Text.RegularExpressions.Regex.Match(ratingWidth, @"(\d+)%").Groups[1].Value; if (int.TryParse(width, out int ratingPercent)) { product.Rating = ratingPercent / 20.0f; // Convert percentage to 5-star scale } } // Extract review count var reviewText = Links.Css("div.total-ratings").FirstOrDefault()?.InnerText; if (!string.IsNullOrEmpty(reviewText)) { var reviewCount = System.Text.RegularExpressions.Regex.Match(reviewText, @"\d+").Value; if (int.TryParse(reviewCount, out int count)) { product.ReviewCount = count; } } // Extract available sizes product.AvailableSizes = Links.Css("div.list.-sizes > span.sku-size") .Select(s => s.InnerText) .ToList(); productList.Add(product); } catch (Exception ex) { // Log error and continue with next product Console.WriteLine($"Error parsing product: {ex.Message}"); } } // Save the scraped product data into a JSONL file. Scrape(productList, "Products.jsonl"); // Handle pagination if needed var nextPageLink = response.Css("a.pagination-next").FirstOrDefault(); if (nextPageLink != null) { var nextPageUrl = nextPageLink.Attributes["href"]; this.Request(nextPageUrl, ParseCategory); } } ``` 这种刮擦购物网站的综合方法可确保捕获所有相关产品信息,同时优雅地处理错误。 对于更高级的应用场景,请探索 [](https://ironsoftware.com/csharp/webscraper/tutorials/webscraping-in-c-sharp-advanced/)`IronWebScraper`中提供的高级 Web scraping 功能。
菜单中的目标元素是什么? 从菜单中抓取链接需要精确的 CSS 选择器。 [API 参考](https://ironsoftware.com/csharp/webscraper/object-reference/api/)提供了有关可用选择器方法的详细信息:
如何同时抓取主分类和子分类? 更新代码以抓取主要类别和所有子链接。 这种方法可确保完整的导航结构捕获: ```csharp public override void Parse(Response response) { // List of Category Links (Root) var categoryList = new List(); // Traverse each 'li' under the fixed menu foreach (var li in response.Css("#menuFixed > ul > li")) { // List of Main Links foreach (var Links in li.Css("a")) { var cat = new Category { URL = Links.Attributes["href"], Name = Links.InnerText, SubCategories = new List(), LastScraped = DateTime.Now }; // List of Subcategories Links foreach (var subCategory in li.Css("a[class=subcategory]")) { var subcat = new Category { URL = subCategory.Attributes["href"], Name = subCategory.InnerText, CategoryType = "Subcategory" }; // Check if subcategory link already exists if (cat.SubCategories.Find(c => c.Name == subcat.Name && c.URL == subcat.URL) == null) { // Add sublinks cat.SubCategories.Add(subcat); } } // Update product count based on subcategories cat.ProductCount = cat.SubCategories.Count; // Add Main Category to the list categoryList.Add(cat); } } // Save the scraped data into a JSONL file. Scrape(categoryList, "Shopping.jsonl"); } ```如何从分类页面中提取产品信息? 有了所有网站类别的链接,就可以开始搜索每个类别中的产品。 在处理产品页面时,[线程安全](https://ironsoftware.com/csharp/webscraper/troubleshooting/thread-safety/)对于优化性能非常重要。 导航至任何类别并检查内容:
产品的 HTML 结构是什么样的? 检查 HTML 结构以了解产品组织: ```html ```我应该创建哪种产品模型? 为该内容建立产品模型。 在使用[购物网站搜索](https://ironsoftware.com/csharp/webscraper/how-to/scraping-from-a-shopping-website/)时,请捕捉所有相关的产品详细信息: ```csharp public class Product { ////// Gets or sets the name. /// ////// The name. /// public string Name { get; set; } ////// Gets or sets the price. /// ////// The price. /// public string Price { get; set; } ////// Gets or sets the image. /// ////// The image. /// public string Image { get; set; } // Additional properties for comprehensive data collection public string Brand { get; set; } public string OldPrice { get; set; } public string Discount { get; set; } public float Rating { get; set; } public int ReviewCount { get; set; } public ListAvailableSizes { get; set; } public string ProductUrl { get; set; } public string SKU { get; set; } public DateTime ScrapedDate { get; set; } } ```如何添加产品抓取功能? 要抓取分类页面,请添加一个新的抓取方法,该方法具有错误处理和数据验证功能: ```csharp public void ParseCategory(Response response) { // List of Products var productList = new List(); // Iterate through product links in the product section foreach (var Links in response.Css("section.products > div > a")) { try { var product = new Product { Name = Links.Css("h2.title > span.name").First().InnerText, Brand = Links.Css("h2.title > span.brand").FirstOrDefault()?.InnerText ?? "Unknown", Price = Links.Css("div.price-container > span.price-box > span.price > span[data-price]").First().InnerText, Image = Links.Css("div.image-wrapper.default-state > img").First().Attributes["src"], ProductUrl = Links.Attributes["href"], SKU = Links.ParentNode.Attributes["data-sku"], ScrapedDate = DateTime.Now }; // Extract old price if available var oldPriceElement = Links.Css("span.price.-old > span[data-price]").FirstOrDefault(); if (oldPriceElement != null) { product.OldPrice = oldPriceElement.InnerText; } // Extract discount percentage var discountElement = Links.Css("span.sale-flag-percent").FirstOrDefault(); if (discountElement != null) { product.Discount = discountElement.InnerText; } // Extract rating information var ratingWidth = Links.Css("div.stars").FirstOrDefault()?.Attributes["style"]; if (!string.IsNullOrEmpty(ratingWidth)) { var width = System.Text.RegularExpressions.Regex.Match(ratingWidth, @"(\d+)%").Groups[1].Value; if (int.TryParse(width, out int ratingPercent)) { product.Rating = ratingPercent / 20.0f; // Convert percentage to 5-star scale } } // Extract review count var reviewText = Links.Css("div.total-ratings").FirstOrDefault()?.InnerText; if (!string.IsNullOrEmpty(reviewText)) { var reviewCount = System.Text.RegularExpressions.Regex.Match(reviewText, @"\d+").Value; if (int.TryParse(reviewCount, out int count)) { product.ReviewCount = count; } } // Extract available sizes product.AvailableSizes = Links.Css("div.list.-sizes > span.sku-size") .Select(s => s.InnerText) .ToList(); productList.Add(product); } catch (Exception ex) { // Log error and continue with next product Console.WriteLine($"Error parsing product: {ex.Message}"); } } // Save the scraped product data into a JSONL file. Scrape(productList, "Products.jsonl"); // Handle pagination if needed var nextPageLink = response.Css("a.pagination-next").FirstOrDefault(); if (nextPageLink != null) { var nextPageUrl = nextPageLink.Attributes["href"]; this.Request(nextPageUrl, ParseCategory); } } ``` 这种刮擦购物网站的综合方法可确保捕获所有相关产品信息,同时优雅地处理错误。 对于更高级的应用场景,请探索 [](https://ironsoftware.com/csharp/webscraper/tutorials/webscraping-in-c-sharp-advanced/)`IronWebScraper`中提供的高级 Web scraping 功能。
如何从分类页面中提取产品信息? 有了所有网站类别的链接,就可以开始搜索每个类别中的产品。 在处理产品页面时,[线程安全](https://ironsoftware.com/csharp/webscraper/troubleshooting/thread-safety/)对于优化性能非常重要。 导航至任何类别并检查内容:
产品的 HTML 结构是什么样的? 检查 HTML 结构以了解产品组织: ```html ```我应该创建哪种产品模型? 为该内容建立产品模型。 在使用[购物网站搜索](https://ironsoftware.com/csharp/webscraper/how-to/scraping-from-a-shopping-website/)时,请捕捉所有相关的产品详细信息: ```csharp public class Product { ////// Gets or sets the name. /// ////// The name. /// public string Name { get; set; } ////// Gets or sets the price. /// ////// The price. /// public string Price { get; set; } ////// Gets or sets the image. /// ////// The image. /// public string Image { get; set; } // Additional properties for comprehensive data collection public string Brand { get; set; } public string OldPrice { get; set; } public string Discount { get; set; } public float Rating { get; set; } public int ReviewCount { get; set; } public ListAvailableSizes { get; set; } public string ProductUrl { get; set; } public string SKU { get; set; } public DateTime ScrapedDate { get; set; } } ```如何添加产品抓取功能? 要抓取分类页面,请添加一个新的抓取方法,该方法具有错误处理和数据验证功能: ```csharp public void ParseCategory(Response response) { // List of Products var productList = new List(); // Iterate through product links in the product section foreach (var Links in response.Css("section.products > div > a")) { try { var product = new Product { Name = Links.Css("h2.title > span.name").First().InnerText, Brand = Links.Css("h2.title > span.brand").FirstOrDefault()?.InnerText ?? "Unknown", Price = Links.Css("div.price-container > span.price-box > span.price > span[data-price]").First().InnerText, Image = Links.Css("div.image-wrapper.default-state > img").First().Attributes["src"], ProductUrl = Links.Attributes["href"], SKU = Links.ParentNode.Attributes["data-sku"], ScrapedDate = DateTime.Now }; // Extract old price if available var oldPriceElement = Links.Css("span.price.-old > span[data-price]").FirstOrDefault(); if (oldPriceElement != null) { product.OldPrice = oldPriceElement.InnerText; } // Extract discount percentage var discountElement = Links.Css("span.sale-flag-percent").FirstOrDefault(); if (discountElement != null) { product.Discount = discountElement.InnerText; } // Extract rating information var ratingWidth = Links.Css("div.stars").FirstOrDefault()?.Attributes["style"]; if (!string.IsNullOrEmpty(ratingWidth)) { var width = System.Text.RegularExpressions.Regex.Match(ratingWidth, @"(\d+)%").Groups[1].Value; if (int.TryParse(width, out int ratingPercent)) { product.Rating = ratingPercent / 20.0f; // Convert percentage to 5-star scale } } // Extract review count var reviewText = Links.Css("div.total-ratings").FirstOrDefault()?.InnerText; if (!string.IsNullOrEmpty(reviewText)) { var reviewCount = System.Text.RegularExpressions.Regex.Match(reviewText, @"\d+").Value; if (int.TryParse(reviewCount, out int count)) { product.ReviewCount = count; } } // Extract available sizes product.AvailableSizes = Links.Css("div.list.-sizes > span.sku-size") .Select(s => s.InnerText) .ToList(); productList.Add(product); } catch (Exception ex) { // Log error and continue with next product Console.WriteLine($"Error parsing product: {ex.Message}"); } } // Save the scraped product data into a JSONL file. Scrape(productList, "Products.jsonl"); // Handle pagination if needed var nextPageLink = response.Css("a.pagination-next").FirstOrDefault(); if (nextPageLink != null) { var nextPageUrl = nextPageLink.Attributes["href"]; this.Request(nextPageUrl, ParseCategory); } } ``` 这种刮擦购物网站的综合方法可确保捕获所有相关产品信息,同时优雅地处理错误。 对于更高级的应用场景,请探索 [](https://ironsoftware.com/csharp/webscraper/tutorials/webscraping-in-c-sharp-advanced/)`IronWebScraper`中提供的高级 Web scraping 功能。
如何添加产品抓取功能? 要抓取分类页面,请添加一个新的抓取方法,该方法具有错误处理和数据验证功能: ```csharp public void ParseCategory(Response response) { // List of Products var productList = new List(); // Iterate through product links in the product section foreach (var Links in response.Css("section.products > div > a")) { try { var product = new Product { Name = Links.Css("h2.title > span.name").First().InnerText, Brand = Links.Css("h2.title > span.brand").FirstOrDefault()?.InnerText ?? "Unknown", Price = Links.Css("div.price-container > span.price-box > span.price > span[data-price]").First().InnerText, Image = Links.Css("div.image-wrapper.default-state > img").First().Attributes["src"], ProductUrl = Links.Attributes["href"], SKU = Links.ParentNode.Attributes["data-sku"], ScrapedDate = DateTime.Now }; // Extract old price if available var oldPriceElement = Links.Css("span.price.-old > span[data-price]").FirstOrDefault(); if (oldPriceElement != null) { product.OldPrice = oldPriceElement.InnerText; } // Extract discount percentage var discountElement = Links.Css("span.sale-flag-percent").FirstOrDefault(); if (discountElement != null) { product.Discount = discountElement.InnerText; } // Extract rating information var ratingWidth = Links.Css("div.stars").FirstOrDefault()?.Attributes["style"]; if (!string.IsNullOrEmpty(ratingWidth)) { var width = System.Text.RegularExpressions.Regex.Match(ratingWidth, @"(\d+)%").Groups[1].Value; if (int.TryParse(width, out int ratingPercent)) { product.Rating = ratingPercent / 20.0f; // Convert percentage to 5-star scale } } // Extract review count var reviewText = Links.Css("div.total-ratings").FirstOrDefault()?.InnerText; if (!string.IsNullOrEmpty(reviewText)) { var reviewCount = System.Text.RegularExpressions.Regex.Match(reviewText, @"\d+").Value; if (int.TryParse(reviewCount, out int count)) { product.ReviewCount = count; } } // Extract available sizes product.AvailableSizes = Links.Css("div.list.-sizes > span.sku-size") .Select(s => s.InnerText) .ToList(); productList.Add(product); } catch (Exception ex) { // Log error and continue with next product Console.WriteLine($"Error parsing product: {ex.Message}"); } } // Save the scraped product data into a JSONL file. Scrape(productList, "Products.jsonl"); // Handle pagination if needed var nextPageLink = response.Css("a.pagination-next").FirstOrDefault(); if (nextPageLink != null) { var nextPageUrl = nextPageLink.Attributes["href"]; this.Request(nextPageUrl, ParseCategory); } } ``` 这种刮擦购物网站的综合方法可确保捕获所有相关产品信息,同时优雅地处理错误。 对于更高级的应用场景,请探索 [](https://ironsoftware.com/csharp/webscraper/tutorials/webscraping-in-c-sharp-advanced/)`IronWebScraper`中提供的高级 Web scraping 功能。
常见问题解答
如何用 C# 从购物网站提取产品数据?
IronWebScraper 可通过 CSS 选择器轻松提取购物网站中的产品数据。您可以创建一个 WebScraper 类,覆盖 Parse 方法,并使用 response.Css() 来定位特定的 HTML 元素,如产品名称、价格和图片。提取的数据可保存为各种格式,包括 JSON 和 JSONL 文件。
创建购物网站搜索器的基本步骤是什么?
使用 IronWebScraper 创建购物网站刮板:1) 创建一个控制台应用程序项目;2) 添加一个继承自 WebScraper 的类;3) 为类别和产品创建数据模型;4) 覆盖 Init() 方法以设置起始 URL;5) 覆盖 Parse() 方法以使用 CSS 选择器提取数据;6) 运行 scraper 以将数据保存为首选格式。
在搜索电子商务网站时,如何处理分层分类结构?
IronWebScraper 允许您通过创建反映父子关系的适当数据模型(如时尚 > 男装 > 鞋)来处理分层结构。您可以使用 CSS 选择器浏览嵌套的 HTML 元素,并以编程方式构建分类树结构,这在使用 IronWebScraper 的高级功能时尤其有用。
分析购物网站 HTML 结构的最佳方法是什么?
在使用 IronWebScraper 搜刮购物网站之前,请使用浏览器开发工具检查 HTML 结构。在 CSS 类和元素层次结构中寻找一致的模式。这种分析可帮助您确定要在 IronWebScraper Parse() 方法中使用的正确 CSS 选择器,以便准确定位产品信息、类别和其他数据元素。
我能否从同一个页面中提取产品列表和分类导航?
是的,IronWebScraper 可以让您从一个页面中提取多种类型的数据。在您的 Parse() 方法中,您可以使用不同的 CSS 选择器同时针对类别链接(如".category-item")和产品列表(如".product-item"),然后将它们保存到不同的输出文件或数据结构中。
如何将刮擦的产品数据保存到文件中?
IronWebScraper 提供了一个内置的 Scrape() 方法,可自动保存提取的数据。只需将数据对象和文件名传递给 Scrape(item, "products.jsonl")。该库支持多种输出格式,包括 JSON、JSONL 和 CSV,因此可以轻松导出抓取的电子商务数据,以便进一步处理。












