Парсинг таблицы C#
Я для себя поставил задачу (как практика, никогда не работал с парсингом сайтов) сделать парсер магазина. Магазин представлен в виде таблицы
ТОВАРЫ ДЛЯ ДОМА
Подушка | 12шт | 400руб
Стул | 3шт | 330руб
Диван | 1шт | 1200руб
Вот мой код
using (HttpRequest req = new HttpRequest())
{
string html = req.Get("https://site.com/").ToString();
doc.LoadHtml(html);
HtmlNode table = doc.DocumentNode.SelectSingleNode(@"//table");
List<ReadOnlyCollection<string>> Elements = new List<ReadOnlyCollection<string>>();
HtmlNodeCollection nodes = table.SelectNodes("//td");
int value = 0;
do
{
List<string> tableRow = new List<string>
{
nodes[value++].InnerText.Trim(),
nodes[value++].InnerText.Trim(),
nodes[value++].InnerText.Trim(),
nodes[value++].InnerText.Trim()
};
Elements.Add(tableRow.AsReadOnly());
} while (value < nodes.Count);
foreach (ReadOnlyCollection<string> cls in Elements)
{
Console.WriteLine("{0} \r\n {1} \r\n {2}", cls[0], cls[1], cls[2]);
}
}
Как можно спарсить в отдельные переменные название категории, и сам товар со всеми столбцами? На пример вывести все товары где количество не меньше 5 шт и не дороже 500рублей Спасибо. Может LINQ как то использовать? Ибо мой код работает не корректно
Ответы (1 шт):
Для удобства создайте класс с нужными вам свойствами
public class TableItem
{
public string Name { get; set; }
public int Count { get; set; }
public int Price { get; set; }
// ...
}
Тогда заполнить коллекцию можно так.
List<TableItem> elements = new List<TableItem>();
for (int i = 0; i <= nodes.Count - 4; i += 4)
{
elements.Add(new TableItem
{
Name = nodes[i].InnerText.Trim(),
Count = int.Parse(nodes[i + 1].InnerText.Replace("шт", "")),
Price = int.Parse(nodes[i + 2].InnerText.Replace("руб", "")),
});
}
Сразу числовые значения лучше распарсить в числовые типы.
Тогда можно будет более-менее удобные Linq запросы
На пример вывести все товары где количество не меньше 5 шт и не дороже 500рублей
foreach (TableItem item in elements.Where(x => x.Count >= 5 && x.Price <= 500))
{
Console.WriteLine(string.Join(Environment.NewLine, item.Name, item.Count, item.Price));
}