public IEnumerable <string> Errors() { return(_node.QuerySelectorAll("div:nth-child(3) > div > div > ul > li").Select(x => x.TextContent).Where(x => x.Trim().Any())); }
public IEnumerable <string> Errors() { return(_node.QuerySelectorAll("#ValidationSummary > div > ul > li").Select(x => x.TextContent).Where(x => x.Trim().Any())); }
public async Task <IEnumerable <IDeal> > Scrape(CancellationToken token) { List <IDeal> deals = new List <IDeal>(); DocumentRequest request = DocumentRequest.Get(Url.Create(URL)); IDocument document = await context.OpenAsync(request, token); token.ThrowIfCancellationRequested(); IHtmlElement body = document.Body; IEnumerable <IHtmlListItemElement> items = body.QuerySelectorAll <IHtmlListItemElement>(".grid-tile"); foreach (IHtmlListItemElement element in items) { IHtmlDivElement titleElement = element.QuerySelector <IHtmlDivElement>(".card-title"); string title = titleElement.TextContent.Trim(); IHtmlAnchorElement linkElement = element.QuerySelector <IHtmlAnchorElement>(".thumb-link"); IHtmlImageElement imageElement = element.QuerySelector <IHtmlImageElement>(".product_image"); IHtmlDivElement priceElement = element.QuerySelector <IHtmlDivElement>(".card-price"); IHtmlDivElement availabilityElement = element.QuerySelector <IHtmlDivElement>(".product-availability-label"); string offerStartDate = availabilityElement.GetAttribute("data-freeofferstartdate"); string offerEndDate = availabilityElement.GetAttribute("data-freeofferenddate"); bool hasStartDate = DateTime.TryParseExact(offerStartDate, "ddd MMM dd HH:mm:ss Z yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime startDate); bool hasEndDate = DateTime.TryParseExact(offerEndDate, "ddd MMM dd HH:mm:ss Z yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime endDate); if (!hasStartDate && !hasEndDate) { logger.Info($"{title} has no start or end date"); continue; } DateTime now = DateTime.Now; if ((hasStartDate && now < startDate) || (hasEndDate && now > endDate)) { logger.Info($"{title} is not active right now"); continue; } string price = priceElement.TextContent.Trim(); if (price.ToLower() != "free to play") { logger.Info($"{title} is not free"); continue; } deals.Add(new Deal { Discount = 100, End = hasEndDate ? endDate : (DateTime?)null, Start = hasStartDate ? startDate : (DateTime?)null, Title = title, Link = $"https://store.ubi.com/{linkElement.GetAttribute("href")}", Image = imageElement.GetAttribute("data-desktop-src") }); } return(deals); }
/// <summary> /// Заполнение данных о товаре с сайта поставщика /// </summary> public async Task <bool> FillByUrl() { bool res = false; if (await Loader.LoadPageAsync(Url)) { // Получение наименования товара IHtmlHeadingElement pageHeader = (IHtmlHeadingElement)Loader.Document.QuerySelectorAll("h1") .Where(item => item.TextContent.Trim().Length > 0) .FirstOrDefault(); if (pageHeader != null) { Name = pageHeader.TextContent.Trim(); } // Получение цены товара IHtmlSpanElement mainPrice = (IHtmlSpanElement)Loader.Document.QuerySelectorAll("span") .Where(item => item.Id != null && item.Id.Trim() == @"main-price") .FirstOrDefault(); if (mainPrice != null) { int mainPriceValue = 0; if (int.TryParse(mainPrice.TextContent.Trim().Replace(" ", string.Empty), out mainPriceValue)) { Price = mainPriceValue; } } // Получение старой цены товара IHtmlDivElement oldPriceElement = (IHtmlDivElement)Loader.Document.QuerySelectorAll("div") .Where(item => item.ClassName != null && item.ClassName.Contains(@"old-price")) .FirstOrDefault(); if (oldPriceElement != null) { Regex rgOldPrice = new Regex(@"^(?<value>\d+)"); Match mtOldPrice = rgOldPrice.Match(oldPriceElement.TextContent.Trim().Replace(" ", string.Empty)); if (mtOldPrice.Success) { int oldPriceValue = 0; if (int.TryParse(mtOldPrice.Groups["value"].ToString(), out oldPriceValue)) { OldPrice = oldPriceValue; } } } // Загрузка списка технических характеристик IHtmlElement techSpecSection = (IHtmlElement)Loader.Document.QuerySelectorAll("section") .Where(item => item.ClassName != null && item.ClassName.Contains(@"tech-specs")) .FirstOrDefault(); if (techSpecSection != null) { var techSpecRowsCollection = techSpecSection.QuerySelectorAll("div") .Where(item => item.ClassName != null && item.ClassName.Contains(@"row")); foreach (IHtmlDivElement techSpecRow in techSpecRowsCollection) { IHtmlSpanElement techSpecName = (IHtmlSpanElement)techSpecRow.QuerySelectorAll("span") .FirstOrDefault(); IHtmlParagraphElement techSpecValue = (IHtmlParagraphElement)techSpecRow.QuerySelectorAll("p") .Where(item => item.ClassName != null && item.ClassName.Contains(@"p-style2")) .FirstOrDefault(); if (techSpecName != null && techSpecValue != null && techSpecName.TextContent.Trim().Length > 0 && techSpecValue.TextContent.Trim().Length > 0) { Options.Add(new InventItemOption(techSpecName.TextContent.Trim(), techSpecValue.TextContent.Trim())); } } } // Загрузка описания товара IHtmlDivElement descrElement = (IHtmlDivElement)Loader.Document.QuerySelectorAll("div") .Where(item => item.Id != null && item.Id.Trim() == @"descr") .FirstOrDefault(); if (descrElement != null) { Descr = descrElement.TextContent.Trim(); } // Формирование списка изображений товара IHtmlUnorderedListElement imagesListElement = (IHtmlUnorderedListElement)Loader.Document.QuerySelectorAll("ul") .Where(item => item.ClassName != null && item.ClassName.Contains(@"pagination")) .FirstOrDefault(); if (imagesListElement != null) { var imagesListCallection = imagesListElement.QuerySelectorAll("img"); foreach (IHtmlImageElement imageItem in imagesListCallection) { if (imageItem.Source != null && imageItem.Source.Length > 0) { Images.Add(Site.PrepareUrl(imageItem.Source)); } } } res = true; } RegisterInventItem(); return(res); }