четверг, 7 июня 2012 г.

C# Agility pack HTML Парсер

В данной статье будет рассмотрен html парсер Agility pack, очень удобен для использования. Намного надёжней, чем регулярные выражения, если честно. Долгое время провозился одно время, так как знаком с ними очень немного =)

Если кто то не в курсе для чего нужен парсер страниц, то объясню вкратце:
Есть какая либо html страница (не важно в виде файла на локальном диске или в интернете),  есть необходимость извлечь из неё определённые данные, которые возможно необходимы для дальнейшей работы.

То есть если в двух словах, то у вас перед глазами сайт google.com и вам нужно загнать в строковую переменную слово Google, извлекая его из исходного кода страницы, из определённого html тега или атрибутов тега.
Но используется для более сложных вычислений =)

Библиотека Agility pack не является стандартной и её надо дополнительно скачивать и внедрять в проект.
Скачать её можно тут. Нас будет интересовать Html Agility Pack 1.4.0 Binaries. Как делать импорт библиотек, можно прочесть тут.

Как работать с парсером. Рассмотрим на примере исходного кода:


private void button1_Click(object sender, EventArgs e)
        {
            // Создаём экземпляр класса
            HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
            // Присваиваем текстовой переменной k html-код
            string k = "<html><head><title>Пример 1</title></head> <body> <div class=\"bla1\">Это простейший пример HTML-документа.</div></body> </html>";
            // Загружаем в класс (парсер) наш html
            doc.LoadHtml(k);
            // Извлекаем всё текстовое, что есть в теге <div> с классом bla1
            HtmlNode bodyNode = doc.DocumentNode.SelectSingleNode("//div[@class='bla1']");
            // Выводим на экран результат работы парсера
            MessageBox.Show(bodyNode.InnerText);

}

Если мы хотим получить значение атрибута какого либо html-тега, например источник изображения (src), то для нахождения данного значения наш код будет выглядеть следующим образом:

private void button2_Click(object sender, EventArgs e)
{
            // Создаём экземпляр класса
            HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
            // Присваиваем текстовой переменной k html-код
            string k = "<html><head><title>Пример 1</title></head> <body> <div class=\"bla1\"><img src=\"https://www.google.ru/images/srpr/logo3w.png\"/>типа изображение</div></body> </html>";
            // Загружаем в класс (парсер) наш html
            doc.LoadHtml(k);
            // Извлекаем значения
            HtmlNode bodyNode = doc.DocumentNode.SelectSingleNode("//div[@class='bla1']/img");
            // Выводим на экран значиение атрибута src
            // у изображения, которое находилось
            // в теге <div> в слассом bla
            MessageBox.Show(bodyNode.Attributes["src"].Value);
            
           
            //pictureBox1.ImageLocation = bodyNode.Attributes["src"].Value;
            
}
Таким образом конструкцию нашего кода можно усложнять, добавлять свои функции. Дальше дело творческое =)

4 коммент.:

Unknown комментирует...

Если в названии класса стоит пробел, тогда возвращает null. Как с этим справиться?

Анонимный комментирует...

Подскажите, пожалуйста вот что. В c# пытаюсь при помощи htmlAgilityPack "пропарсить" главную страницу яндекса, на предмет курса валют. Делаю через xPath путь беру из Chrome по нажатию на F12, HAP возвращает null. Пытаюсь "по-ступенчато" сделать, начиная от /html/body/div[] и т. п. Пока в этом пути стоит div[1] или [2], все нормально, возвращает код, но как только ставлю 3 или нужную мне 5-ку, получаю null. Может я что-то не правильно делаю?
/html/body/div[5]/table/tr[2]/td[3]/div/div/div[2]/table[1] Путь таков.

Unknown комментирует...

Здравствуйте, а если мне надо скопировать весь текст, который выводится в браузер, есть множество разных HTML-файлов, в некоторых за вывод текста отвечают скрипты, например, td ALIGN=left VALIGN=TOP COLSPAN=3 ROWSPAN=6> script document.write(eBtn) /script /td.
Можно ли с помощью AgilityPack сначала открыть файл в браузере(в фоновом режиме), скопировать оттуда весь выведенный текст, а потом закрыть браузер? Или как-то по-другому, главное, чтобы текст скопировался) Спасибо!

Анонимный комментирует...

Спасибо большое за статью, очень помогло.

Отправить комментарий

TROCKII БЛОГ Copyright © 2012 | Template created by Lev Trockii |