Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/21: Рейтинг темы: голосов - 21, средняя оценка - 5.00
8 / 6 / 3
Регистрация: 24.05.2013
Сообщений: 43
.NET 4.x

Парсинг сайтов

28.04.2020, 16:22. Показов 4629. Ответов 3
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Приветствую! Пишу парсер сайтов, задумка следующая - в это нелёгкое время мой кот всё равно хочет ходить в туалет, а народ нищает, поэтому хочу спарсить на всех популярных интернет-магазинах наполнитель для туалета силикагелевый, в список заносится информация о цене, названии и ссылка на товар, затем из названия "вычленяется" объём товара и высчитывается цена за единицу товара, после чего список упорядочивается по этому параметру и выгружается в CSV файл. Для парсинга решено использовать библиотеку AngleSharp.

Был создан класс OutList в качестве типа данных, там заданы необходимые поля и методы.
Был создан класс Ozon в качестве парсера сайта ozon, решил начать именно с этого магазина.
Парсер грузит страницу прямо по ссылке с установленными фильтрами, т.е. ничего к ссылке не добавляет (пока пытаюсь загрузить хотя бы 1 страницу, потом в цикл засуну)
Дальше методом Parse я пытаюсь из полученной страницы по тегам вытащить нужную мне информацию - цену, название и ссылку, затем занести данный товар в список.

Собственно на этом этапе у меня и возникли трудности, парсер я пишу впервые и многое не понимаю:
1) Теги по которым я ищу информацию постоянно меняются, как с этим бороться я не понимаю
2) На странице 36 товаров, мой парсер записывает только 4
3) Пробелы из строки цены так и не удаляются из-за чего не преобразуется в int

Подскажите, что я делаю не так и как мне побороть эти проблемы, прикрепляю листинг классов и проект целиком

P.S. На обилие комментариев внимание не обращайте, это по совместительству моя самостоятельная работа по учёбе, преподаватель требует комментировать каждую строчку

Ozon
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using ShopsParser;
using Leaf.xNet;
using AngleSharp.Html.Parser;
 
namespace ShopsParser
{
    class Ozon
    {
        //Метод получения исходного кода страницы
        public static string GetPage(string link)
        {
            HttpRequest request = new HttpRequest();
            //Задание атрибутов пакета, чтобы получить только нужный пакет от сервера
            /*request.AddHeader("Accept-Encoding", "gzip, deflate");
            request.AddHeader("Accept-Language", "ru,en;q=0.9");
            request.AddHeader("Cache-Control", "max-age=0");
            request.AddHeader("Host", "www.ozon.ru");
            request.AddHeader("Referer", link);
            request.AddHeader("Upgrade-Insecure-Requests", "1");*/
            //request.AddHeader(HttpHeader.Accept, "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9");
            request.KeepAlive = true;
            request.UserAgent = Http.ChromeUserAgent();
 
            string response = request.Get(link).ToString();
            return response;
        }
        
        public static OutList Parse(string Response)
        {
            OutList List1 = new OutList();  //Создание экземпляра класса OutList - список товаров в данном магазине
            string BaseUrl = "https://www.ozon.ru"; //Создание строки BaseUrl с префиксом для формирования url товаров
 
            HtmlParser HP = new HtmlParser();   //Создание экземпляра парсера
            var Doc = HP.ParseDocument(Response);   //Создание переменной Doc и присвоение ей результата парсинга страницы
            string box = Doc.QuerySelector("div.widget-search-result-container.ap2").InnerHtml; //Тут список всех товаров на странице по ним будет цикл 
 
            foreach (var tmp in Doc.QuerySelectorAll("div.a0u9"))
            {
                string name = tmp.QuerySelector("a.a2h6.tile-hover-target").InnerHtml;    //Выбор названия товара
                string price;
                try
                {
                    price = tmp.QuerySelector("span.a3l9.a3m").InnerHtml;    //Выбор цены товара если она оказалась со скидкой
                }
                catch
                {
                    price = tmp.QuerySelector("span.a3l9").InnerHtml;    //Выбор цены товара
                }
                price = price.Substring(0, price.Length - 2);   //Обрезка у цены знака рубля
                price = price.Replace(" ", ""); //Удаление пробелов из строки цены
                string url = tmp.QuerySelector("a.a2h6.tile-hover-target").GetAttribute("href");    //Выбор ссылки товара
                url = BaseUrl + url;    //Добавление к url начальной части
                List1.Add(name, url, Convert.ToInt32(price));   //Добавление в список полученного товара
            }
 
            //List1.Print();
            return List1;
        }
    }
}


OutList
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace ShopsParser
{
    class OutList
    {
        public class Node
        {
            public string Data;
            public string Url;
            public int Price;
            public float Amount;
            public float UnitPrice;
 
            public Node(string data, string url, int price)
            {
                this.Data = data;
                this.Url = url;
                this.Price = price;
            }
        }
 
        private int count = 0;
        private int ArrayCount = 8;
        Node[] array = new Node[8];
 
        public int Count
        {
            get { return count; }
        }
 
        public void Allow(int count)
        {
            while (count > ArrayCount)
            {
                Node[] temp = new Node[ArrayCount * 2];
                for (int i = 0; i < ArrayCount; i++)
                {
                    temp[i] = array[i];
                }
                array = temp;
                ArrayCount = ArrayCount * 2;
            }
        }
 
        public void Add(string data, string url, int price)
        {
            Allow(count + 1);
            array[count] = new Node(data, url, price);
            count++;
        }
 
        public void Add(Node node)
        {
            string data = node.Data;
            string url = node.Url;
            int price = node.Price;
            Add(data, url, price);
        }
 
        public OutList Merge (OutList list1, OutList list2)
        {
            for (int i = 0; i < list2.count; i++)
            {
                list1.Add(list2[i]);
            }
            return list1;
        }
 
        public void Calculate()
        {
            //Тут должно быть вычисление объёма из строки а затем цены за единицу товара
        }
 
        public void Sort()
        {
            //Тут должна быть сортировка по цене
        }
 
        public void Print()
        {
            //Тут надо допилить чтобы по ширине колоки были равны содержимому
            Console.WriteLine("|   Name   |   URL   |   Price   |   Amount   |   UnitPrice   |");
            for (int i = 0; i < ArrayCount; i++)
            {
                Console.WriteLine("| " + array[i].Data + " | " + array[i].Url + " | " + array[i].Price + " |" + " | " + array[i].Amount + " | " + array[i].UnitPrice + " |");
            }
        }
 
        public void PrintFile()
        {
            //Тут должна быть выгрузка в .csv
        }
 
        public Node this[int pos]
        {
            get
            {
                return array[pos];
            }
            set
            {
                array[pos] = value;
            }
        }
    }
}


Program
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Leaf.xNet;
using AngleSharp.Html.Parser;
 
namespace ShopsParser
{
    class Program
    {
        static void Main(string[] args)
        {
            OutList result = new OutList();  //Создание списка куда будут записываться результаты
 
            //Переключение страниц в цикле по try/catch
            string response = Ozon.GetPage("https://www.ozon.ru/category/napolniteli-12380/?materialfiller=51311&page=1"); //Получение страницы сайта
            OutList OzonList = Ozon.Parse(response);  //Парсинг страницы
 
 
 
            result.Print();
            Console.ReadKey();
        }
    }
}


Вдохновлялся этим плейлистом:
Кликните здесь для просмотра всего текста
Вложения
Тип файла: rar ShopsParser.rar (8.38 Мб, 10 просмотров)
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
28.04.2020, 16:22
Ответы с готовыми решениями:

Парсинг сайтов, написанных на javascript
Мне нужно на C# сделать парсинг сайта, написанного на javascript. Как это сделать, есть ли какие-то примеры в интернете и может...

К какому разделу относится парсинг сайтов и какая есть литература
Доброго времени суток. Меня интересует парсинг сайтов. С одного сайта необходимо постоянно заливать информацию по погоде (скачивать csv...

Парсинг динамических сайтов
Всем привет! Ищу способы получения HTML кода сайтов которые подгружают данные путем javascript-a. Стандартные способы webrequest,...

3
управление сложностью
 Аватар для Почтальон
1693 / 1306 / 259
Регистрация: 22.03.2015
Сообщений: 7,545
Записей в блоге: 5
28.04.2020, 19:16
Цитата Сообщение от BROSovod Посмотреть сообщение
Подскажите, что я делаю не так и как мне побороть эти проблемы, прикрепляю листинг классов и проект целиком
т.е. думаете вот так просто взять, и понять как парсить ? а в веб-технологиях сильно разбираетесь? понимаете почему
Цитата Сообщение от BROSovod Посмотреть сообщение
Теги по которым я ищу информацию постоянно меняются
? Это больше похож на коммерческий проект, чем на тот же курсач (либо источники парсинга возьмите другие). Я это к тому, что разрабы там не такие дураки сидят и позволяют всякие вольности
0
8 / 6 / 3
Регистрация: 24.05.2013
Сообщений: 43
28.04.2020, 22:11  [ТС]
Цитата Сообщение от Почтальон Посмотреть сообщение
Это больше похож на коммерческий проект, чем на тот же курсач (либо источники парсинга возьмите другие).
Это не курсач) Это лабораторная работа на тему Data mining, со свободной постановкой задачи, а поскольку мне и правда приходится искать коту наполнитель, то я решил объединить эти 2 момента, коммерции тут никакой и близко нет, источники такие исключительно потому что я ими пользуюсь, я понял, что управление сайта ozon не хочет, чтобы их парсили, что ж мне это тоже не так сильно нужно, как я уже говорил планировалось несколько магазинов - одним будет меньше.

Цитата Сообщение от Почтальон Посмотреть сообщение
т.е. думаете вот так просто взять, и понять как парсить ?
Наша система образования считает, что да, мне приходится подстраиваться, хотел вот помощи на профильном форуме найти.
0
Злой няш
 Аватар для I2um1
2136 / 1505 / 565
Регистрация: 05.04.2010
Сообщений: 2,881
28.04.2020, 22:29
Использовать API, если оно есть, иначе:
- Выучить, что есть XPath, и достать значение 1 запросом
- Проанализировать несколько страниц и определить, что от страницы к странице не меняется, как выполняется навигация
- Лучше использовать HtmlAgilityPack и HttpClient

Ничего работать не будет, если сайт стильный, молодежный и рисует все с помощью JavaScript. В этом случае есть два подхода:
1. Использовать библиотеку для эмуляции JavaScript.
2. Загрузить страницу браузером и только потом парсить.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
28.04.2020, 22:29
Помогаю со студенческими работами здесь

Парсинг сайтов
Подскажите пожалуйста как можно парсить сайты с помощью json, webclient и htmlagility. Прочитал множество статей, но там идет упор на XML.

Парсинг сайтов
Здравствуйте, подскажите хорошую библиотеку для парсинга сайтов и желатьльно ссылку на документацию, заранее спасибо!

парсинг сайтов
Здравствуйте форумчане, у меня вопрос,к примеру есть сайт wday.ru, мне нужно спарсить все новости во всех разделах ../moda-shopping/.. и...

Парсинг сайтов
Добрый день, такая ситуация: делаю парсер нескольких сайтов. парсю с помощью simple_html_dom.php при открытии сайта берем с...

Парсинг сайтов на Python
Всем привет. В программировании новичок. Появилась необходимость спарсить страничку Пробовал через BeautifulSoup. Получился такой код: ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru