Страницы

Поиск по вопросам

четверг, 18 октября 2018 г.

Как правильно парсить с помощью AngleSharp?

Всем привет! Много тем уже перечитал похожих, но в них в основном какие-то частности спрашивались. Очень согласен вот с этими словами. Ну, честно говоря, вообще ничего непонятно. Понял, что информация из html парсится либо через LINQ, либо через CSS селекторы. С первым вообще не знаком, CSS знаю поверхностно. Но все равно такой вариант мне интуитивно что ли ближе, поэтому хотелось бы ответы получить в виде CSS селекторов.
Сразу вопрос: всю ли инфу можно запарсить обоими способами? Или есть только случаи, когда работает только один из способов? Или же есть случаи, где вообще нельзя?)
Теперь непосредственно к задаче. Хочу запарсить данные контактов с сайта домофонда. Например, возьмем вот эту страницу. Парсю всю страницу для начала
var parser = new HtmlParser(); var doc = parser.Parse("ссыль");
Как, например, запарсить имя? Смотрю исходник, вижу, что имя находится в блоке div class="df_panel". Вроде бы этот блок с уникальным названием, поэтому можно сузить поиск
var div = doc.QuerySelector("div.df_panel");
Вот тут сразу начинаются вопросы. Сам разобрался, что, если в блоке div указывается название класса, то пишется так, как приведено. Если, например, div id="test", то уже запрос по-другому пишется (долго доходило на основе кучу примеров из разных форумов)
var div = doc.QuerySelector("div[id="test"");
Вот где по этому поводу что-то написано? Я так понимаю, что здесь применяются какие-то регулярные выражения. Может они аналогичные каким-то другим парсерам, как, например, написано тут, что AngleSharp очень похож на Fizzler. Но что, если у меня это локально возникшая задача, и не с какими другими парсерами я дело не имел? Как я должен понять, что именно мне писать?
Ладно, отвлекся. Див ближайший для сужения круга поиска получили. (Опять отвлекусь - кстати, а как быть, если бы его вообще не было? Можно ли каким-то образом получить определенные данные, если нет уникальных идентификаторов, посредством которых сужается постепенно зона поиска нужного значения?). Итого видим, что имя записано в тег заголовка

НУЖНОЕ ИМЯ
. Как получить это значение? Было бы возможно вытащить имя, если бы оно было записано вообще без тега заголовка?
Пока на этом вопросы задавать перестану. Буду благодарен за любые объяснения. Желательно очень получить ответы на более общие вопросы (например, по поводу, как я предполагаю, этих регулярных выражений с хелпом или хорошими примерами), тогда может с остальной частью я и сам разберусь.


Ответ

Самое важное
Перво-наперво, вам нужно выучить CSS селекторы. А для лучшего понимания, хотя бы еще основы HTML. Сделать это можно, например, на HTML Academy. Бесплатно.
Я бы еще добавил, что никакой магии нет- все выборки AngleSharp это стандартные селекторы CSS, а не что-то необычное. (c) ReinRaus
Отвечу на ваш вопрос:
Но что, если у меня это локально возникшая задача, и не с какими другими парсерами я дело не имел? Как я должен понять, что именно мне писать?
Чтобы понять, что надо писать, повторюсь, вам надо выучить CSS селекторы. Сделать это можно, например, здесь: "Знаете ли вы селекторы?".
Приведу здесь краткую выжимку из упомянутой выше статьи:
Основные виды селекторов
Основных видов селекторов всего несколько:
* – любые элементы. div – элементы с таким тегом. #id – элемент с данным id .class – элементы с таким классом. [name="value"] – селекторы на атрибут (см. далее). :visited – «псевдоклассы», остальные разные условия на элемент (см. далее).
Селекторы можно комбинировать, записывая последовательно, без пробела:
.c1.c2 – элементы одновременно с двумя классами c1 и c2 a#id.c1.c2:visited – элемент a с данным id, классами c1 и c2, и псевдоклассом visited
Отношения
В CSS3 предусмотрено четыре вида отношений между элементами.
Самые известные вы наверняка знаете:
div p – элементы p, являющиеся потомками div. div > p – только непосредственные потомки Есть и два более редких:
div ~ p – правые соседи: все p на том же уровне вложенности, которые идут после div. div + p – первый правый сосед: p на том же уровне вложенности, который идёт сразу после div (если есть).
Селекторы атрибутов
На атрибут целиком:
[attr] – атрибут установлен, [attr="val"] – атрибут равен val.
На начало атрибута:
[attr^="val"] – атрибут начинается с val, например value. [attr|="val"] – атрибут равен val или начинается с val-, например равен val-1. На содержание: [attr*="val"] – атрибут содержит подстроку val, например равен myvalue. [attr~="val"] – атрибут содержит val как одно из значений через пробел. Например: [attr~="delete"] верно для edit delete и неверно для undelete, а еще неверно для no-delete
На конец атрибута:
[attr$="val"] – атрибут заканчивается на val, например равен myval
Где попрактиковаться?
CSS Diner - здесь нужно выбирать элемент, соответствующий указанному CSS правилу. HTML Academy - здесь можно изучить основы верстки. htmlbook - справочник по css селекторам и html тегам.
Ответы на остальные вопросы
Вот где по этому поводу что-то написано? Я так понимаю, что здесь применяются какие-то регулярные выражения.
Это не регулярные выражения, а CSS селекторы. Об этом я написал выше.
Можно ли каким-то образом получить определенные данные, если нет уникальных идентификаторов, посредством которых сужается постепенно зона поиска нужного значения?
Да, комбинируя дочерние элементы по любому признаку. Например, первый потомок в родителе (* > *:first-child), точно второй по счету элемент p внутри своего родителя (p:nth-child(2)), не пустой a элементы (a:not(:empty)) и так далее.
Итого видим, что имя записано в тег заголовка

НУЖНОЕ ИМЯ
. Как получить это значение? Было бы возможно вытащить имя, если бы оно было записано вообще без тега заголовка?
Если я правильно понял, и имеется в виду значение, не обернутое в какой-либо тег, то все равно ответ будет – да. Можно выполнить поиск по тексту. Для этого конкретного случая решение в виде селектора будет таким: h6[itemprop="name"]
как только не пробовал. Не парсит с .df_panel
Ваш код из комментариев использует метод QuerySelector, который, как я понимаю, выбирает первый элемент с указанным селектором. Первый .df_panel из шести на странице не содержит элемента h6. Поэтому у вас ничего и не находит. Еще раз подчеркну: на странице шесть элементов .df_panel
Код для выборки нужного вам элемента
var seller = doc.QuerySelector("[itemprop='seller']"); var name = seller.QuerySelector("[itemprop='name']").Text();

Комментариев нет:

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