#c_sharp #html #css #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. Но что, если у меня это локально
возникшая задача, и не с какими другими парсерами я дело не имел? Как я должен понять,
что именно мне писать?
Ладно, отвлекся. Див ближайший для сужения круга поиска получили. (Опять отвлекусь
- кстати, а как быть, если бы его вообще не было? Можно ли каким-то образом получить
определенные данные, если нет уникальных идентификаторов, посредством которых сужается
постепенно зона поиска нужного значения?). Итого видим, что имя записано в тег заголовка
НУЖНОЕ ИМЯ
. Как получить это значение? Было бы возможно вытащить
имя, если бы оно было записано вообще без тега заголовка?
Пока на этом вопросы задавать перестану. Буду благодарен за любые объяснения. Желательно
очень получить ответы на более общие вопросы (например, по поводу, как я предполагаю,
этих регулярных выражений с хелпом или хорошими примерами), тогда может с остальной
частью я и сам разберусь.
Ответы
Ответ 1
Самое важное
Перво-наперво, вам нужно выучить 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();
Ответ 2
Но что, если у меня это локально возникшая задача, и не с какими
другими парсерами я дело не имел? Как я должен понять, что именно мне
писать?
Выше ответили про то, что вам нужно знать css селекторы, однако поскольку вопрос
светится в поисковиках (вопросов на ru-so не так много) - допишу ещё полезную ссылку
по теме.
В официальных репозиториях AngleSharp на гитхабе есть демо-приложение.