Как вытянуть значение из парсера на c#?
как вытянуть значение из парсера на c#. собственно есть парсер и мне надо вытянуть значение в отдельную переменную. Сам парсер собирает значение курса доллара с сайта banki.ru
но как это сделать я не знаю
вот код
Episode.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ScrapingDollarRate { public class Episode { public string OverallNumber { get; set; } public string Title { get; set; } //public string Directors { get; set; } //public string WrittenBy { get; set; } //public string Released { get; set; } } } |
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ScrapingDollarRate { public class Episode { public string OverallNumber { get; set; } public string Title { get; set; } //public string Directors { get; set; } //public string WrittenBy { get; set; } //public string Released { get; set; } } }
main.cs
using System; using HtmlAgilityPack; using CsvHelper; using System.Globalization; namespace ScrapingDollarRate { class Program { static void Main(string[] args) { string url = "https://www.banki.ru/products/currency/usd/"; var web = new HtmlWeb(); var document = web.Load(url); var nodes = document.DocumentNode.SelectNodes("//div[contains(@class, 'Flexbox__sc-wtbhrg-0 fEdnEg')]"); List<Episode> episodes = new List<Episode>(); if (nodes == null) { Console.WriteLine("Null"); } else { foreach (var node in nodes) { episodes.Add(new Episode() { OverallNumber = HtmlEntity.DeEntitize(node.SelectSingleNode("//div[contains(@class, 'Text__sc-j452t5-0 hDxmZl')]").InnerText), Title = HtmlEntity.DeEntitize(node.SelectSingleNode("//div[contains(@class, 'Text__sc-j452t5-0 bCCQWi')]").InnerText) // Мне надо чтобы значение этого Title можно было поместить в условную var x и отправить дальше по коду }); } using (var writer = new StreamWriter("output.csv")) using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture)) { csv.WriteRecords(episodes); } } } } } |
using System; using HtmlAgilityPack; using CsvHelper; using System.Globalization; namespace ScrapingDollarRate { class Program { static void Main(string[] args) { string url = "https://www.banki.ru/products/currency/usd/"; var web = new HtmlWeb(); var document = web.Load(url); var nodes = document.DocumentNode.SelectNodes("//div[contains(@class, 'Flexbox__sc-wtbhrg-0 fEdnEg')]"); List<Episode> episodes = new List<Episode>(); if (nodes == null) { Console.WriteLine("Null"); } else { foreach (var node in nodes) { episodes.Add(new Episode() { OverallNumber = HtmlEntity.DeEntitize(node.SelectSingleNode("//div[contains(@class, 'Text__sc-j452t5-0 hDxmZl')]").InnerText), Title = HtmlEntity.DeEntitize(node.SelectSingleNode("//div[contains(@class, 'Text__sc-j452t5-0 bCCQWi')]").InnerText) // Мне надо чтобы значение этого Title можно было поместить в условную var x и отправить дальше по коду }); } using (var writer = new StreamWriter("output.csv")) using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture)) { csv.WriteRecords(episodes); } } } } }
Дополнительно:
Простите, ЧТО?
Episode.ch
Откуда у вас .h файл в C# взялся?
Пожалуйста, дополните ваш вопрос этой и другими подробностями, которые вам могут показаться нужными.
Иначе нам тут придется дожидаться телепата, который прочитает нужные для ответа данные прямо в вашем мозгу, или ясновидящего, который сможет увидеть их в своем хрустальном шаре.
PS Мой комментарий такой язвительный по форме потому, что мне показалось, что вы даже не взяли на себя труд подумать над вопросом, а решили напрячь сообщество, не напрягаясь сами. Если я ошибаюсь, то приношу свои извинения за форму. Но содержания это не отменяет: для ответа на ваш вопрос данных недостаточно.
.. но все зависит от целей.. а HtmlAgilityPack... собрался на пенсию что ли? ))
я тогда просто ссылку на гитхаб кину?))
https://github.com/Zakarayaev/ScrapingDollarRate
на HtmlAgilityPack.CssSelectors все равно предупреждение... но уже все равно завтра ))
я сначала тоже в корневой папке искал, потом нашел))
нашел, напомните теперь чего в супе не хватает?
OverallNumber,Title Обновление: 10.02.2024 09:45,"90,89 ₽" Обновление: 10.02.2024 09:45,"90,89 ₽" Обновление: 10.02.2024 09:45,"90,89 ₽" |
OverallNumber,Title Обновление: 10.02.2024 09:45,"90,89 ₽" Обновление: 10.02.2024 09:45,"90,89 ₽" Обновление: 10.02.2024 09:45,"90,89 ₽"
что по смыслу вы ожидаете в Title?
после просмотра output.csv догадка пришла сразу.. осваивайте отладчик ;)))
ps как вариант
1
public class Episode { public string Title { get; set; } public string OverallNumber { get; set; } } |
public class Episode { public string Title { get; set; } public string OverallNumber { get; set; } }
2
episodes.Add(new Episode() { Title = HtmlEntity.DeEntitize(node.SelectSingleNode("//div[contains(@class, 'Text__sc-j452t5-0 hDxmZl')]").InnerText), OverallNumber = HtmlEntity.DeEntitize(node.SelectSingleNode("//div[contains(@class, 'Text__sc-j452t5-0 bCCQWi')]").InnerText) // тут внимательно! я меняю местами переменные, полагая что токов их смысл. но не запросы! ))) }); |
episodes.Add(new Episode() { Title = HtmlEntity.DeEntitize(node.SelectSingleNode("//div[contains(@class, 'Text__sc-j452t5-0 hDxmZl')]").InnerText), OverallNumber = HtmlEntity.DeEntitize(node.SelectSingleNode("//div[contains(@class, 'Text__sc-j452t5-0 bCCQWi')]").InnerText) // тут внимательно! я меняю местами переменные, полагая что токов их смысл. но не запросы! ))) });
3Title,OverallNumber
Обновление: 10.02.2024 10:05,"90,89 ₽"
Обновление: 10.02.2024 10:05,"90,89 ₽"
Обновление: 10.02.2024 10:05,"90,89 ₽"
.. или уточняйте вопрос? ))
pps а еще нюансики с культурой, чаще разделитель в csv это ";" тогда тот же excel открывает как таблицу сразу... а у вас "," .. это видно по заголовку сразу ))
как вам надо - решайте сами ))у меня на ура прошло так ))
var csv = new CsvWriter(writer, CultureInfo.CurrentCulture) // если у тебя региональные настройки не РФ, все равно так выдаст именно под дефолт твоих настроек |
var csv = new CsvWriter(writer, CultureInfo.CurrentCulture) // если у тебя региональные настройки не РФ, все равно так выдаст именно под дефолт твоих настроек
ppps
Мне надо чтобы значение этого Title можно было поместить в условную var x и отправить дальше по коду
а зачем? ну или в чем трудности? Console.WriteLine(episodes[0].Title); ;)))
- я правильно понял, что тебя интересует метка времени? на момент скачивания страницы, возможно она одна для всех валют (если не только бакс интересует)тогда как вариант
class Program { static void Main(string[] args) { string url = "https://www.banki.ru/products/currency/usd/"; var web = new HtmlWeb(); var document = web.Load(url); var nodes = document.DocumentNode.SelectNodes("//div[contains(@class, 'Flexbox__sc-wtbhrg-0 fEdnEg')]"); List<Episode> episodes = new List<Episode>(); var t = ""; if (nodes == null) Console.WriteLine("Null"); else { t = HtmlEntity.DeEntitize(nodes[0].SelectSingleNode("//div[contains(@class, 'Text__sc-j452t5-0 hDxmZl')]").InnerText); foreach (var node in nodes) episodes.Add(new Episode() { Title = t, OverallNumber = HtmlEntity.DeEntitize(node.SelectSingleNode("//div[contains(@class, 'Text__sc-j452t5-0 bCCQWi')]").InnerText) }); using (var writer = new StreamWriter("output.csv")) using (var csv = new CsvWriter(writer, CultureInfo.CurrentCulture)) csv.WriteRecords(episodes); } Console.WriteLine(t); } }
class Program { static void Main(string[] args) { string url = "https://www.banki.ru/products/currency/usd/"; var web = new HtmlWeb(); var document = web.Load(url); var nodes = document.DocumentNode.SelectNodes("//div[contains(@class, 'Flexbox__sc-wtbhrg-0 fEdnEg')]"); List<Episode> episodes = new List<Episode>(); var t = ""; if (nodes == null) Console.WriteLine("Null"); else { t = HtmlEntity.DeEntitize(nodes[0].SelectSingleNode("//div[contains(@class, 'Text__sc-j452t5-0 hDxmZl')]").InnerText); foreach (var node in nodes) episodes.Add(new Episode() { Title = t, OverallNumber = HtmlEntity.DeEntitize(node.SelectSingleNode("//div[contains(@class, 'Text__sc-j452t5-0 bCCQWi')]").InnerText) }); using (var writer = new StreamWriter("output.csv")) using (var csv = new CsvWriter(writer, CultureInfo.CurrentCulture)) csv.WriteRecords(episodes); } Console.WriteLine(t); } }
- #, спасибо большое, но есть проблема, когда я делаю переменную со значением Title, то вылезает ошибка "The input string '90,89 ₽' was not in a correct format.'"
то есть
int x = Convert.ToInt32(episodes[1].Title); // я не стал менять местами Title и OverallNumberи когда запускаю код вылезает выше указанная ошибка
и если что я уже пытался найти решение для этой ошибки, но ничего не получилось
- Ali-Muhammad, кхм..
- определитесь со смыслом именования полей public class Episode
-
я не стал менять местами Title и OverallNumber
.. ну.. тут вам, как творцу виднее.. при условии понимания )).. у меня чувство, что надо поменять..
- int x = Convert.ToInt32(episodes[1].Title); если все еще не освоили отладчик, добавте выше строкуConsole.WriteLine(episodes[1].Title); и тут много нюансов.. episodes точно не пустая?.. тогда первый элемент индексируется не с "1" а с "0".. (принцип нумерации во всех си-подобных языках.. - #, я так и делаю, но ошибка все равно есть
- Ali-Muhammad, если все остальное вы вполне понимаете, тогда еще тонкости
- курс у вас парсится с обозначением валюты
90,89 ₽
..
- Convert.ToInt32 его не ждет (на сколько я помню).. по тому и ломается..
- и снова культура, вам нужна ваша дефолтная, а еще уверенность что в качестве разделителя знаков? запятая или точка?.. все это легко проверить малюсенькой тестовой программой. ну и при необходимости репарсить исходную строку (замена запятой на точку, или наоборот, возможно вырезание знака рубля.. но может при правильном разделителе и слопает? напишите о результата )) - #, извините, просто я в парсингом начал заниматься буквально неделю назад и ровным счетом ничего не понял, можно чуть-чуть полегче объяснить?)
- - CultureInfo.CurrentCulture
- сделай малюсенькую программку для разных тестов Convert.ToInt32 - Ali-Muhammad,
сделай малюсенькую программку для разных тестов Convert.ToInt32
варианты для тестов:
- 32.32
- 32,32
- 32,32 ₽
.. и так далее - Ali-Muhammad, думаю я пальцы сотру быстрее, чем придет понимание от такой тестовой проги )))
- Ali-Muhammad, а еще, может https://learn.microsoft.com/ru-ru/dotnet/api/syste...
- Ali-Muhammad, слушай.. конкретно тупим )))))))))))
какое на фиг целочисленное значение???... если копейки не важны - обрезать все, после запятой.. и ее тоже ))) - Ali-Muhammad, в модифицированной (по именам полей) версии, так прошло
Console.WriteLine(Convert.ToDecimal(episodes[0].OverallNumber.TrimEnd('₽')));
Console.WriteLine(Convert.ToDecimal(episodes[0].OverallNumber.TrimEnd('₽')));
- #, СПАСИБО ВАМ ОГРОМНОЕ, ОТ ВСЕЙ ДУШИ. КЛЯНУСЬ НЕ ЗНАЮ КАК ВАС БЛАГОДАРИТЬ!!!
- Ali-Muhammad, отметки тут достаточно ))
на будущее, при работе с денежными величинами, особенно с дробной частью, типа рубли/копейки, доллары/центы (хотя не все валюты в мире имеют "мелочь" )).. традиционно считается корректнее Decimal, но не float/double...
потихоньку разберёшься, удачи )) - @mindtesпонял, еще раз спасибо вам
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос



Для того чтобы вытянуть значение из парсера на C#, вам необходимо использовать библиотеку для парсинга HTML, такую как HtmlAgilityPack. Эта библиотека позволяет удобно работать с HTML-документами, извлекая нужные элементы.
Прежде всего, вам необходимо загрузить HTML-страницу, с которой вы хотите извлечь данные. Для этого используйте класс HtmlWeb:
HtmlWeb web = new HtmlWeb(); HtmlDocument doc = web.Load("http://example.com/page.html");Затем, используя XPath или LINQ to HTML, можно найти нужный элемент на странице и получить его значение. Например, если вам нужно извлечь значение из тега
с определенным классом, можно сделать следующим образом:
HtmlNode node = doc.DocumentNode.SelectSingleNode("//p[@class='classname']"); string value = node.InnerText; Console.WriteLine(value);Если вам необходимо извлечь несколько значений, можно воспользоваться методами SelectNodes и LINQ to HTML:
HtmlNodeCollection nodes = doc.DocumentNode.SelectNodes("//div[@class='container']/p"); foreach (HtmlNode node in nodes) { string value = node.InnerText; Console.WriteLine(value); }Таким образом, используя HtmlAgilityPack и LINQ to HTML, вы сможете удобно извлекать нужные значения из парсера на C#. Не забывайте обрабатывать возможные исключения при парсинге и проверять наличие нужных элементов на странице.