Не понимаю логику работы FindChildByXPath()

  • Автор темы Автор темы Dmitriy Ka
  • Дата начала Дата начала

Dmitriy Ka

Client
Регистрация
03.05.2016
Сообщения
951
Реакции
737
Баллы
93
Каждый раз когда использую метод FindChildByXPath(), каждый раз у меня ломается мозг.

Есть коллекция HtmlElement из которой мне нужно дернуть другую коллекцию HtmlElement.
Для примера возьмем блоки поисковой выдачи (блок1, блок2, блок3 ...)
Из этих блоков я хочу забрать HtmlElement: Заголовок, Ссылка, Описание.

Я собираю коллекцию этих блоков
tab.FindElementsByXPath();

Потом форичем получаю уже нужные HtmlElement: Заголовок, Ссылка, Описание.
C#:
Развернуть Свернуть Копировать
foreach (var item in SearchResultCollection)
{
    var title = item.FindChildByXPath(RESULT_TITLE, 0);
    var link = item.FindChildByXPath(RESULT_LINK, 0);
    var description = item.FindChildByXPath(RESULT_DESCRIPTION, 0);

    Title.Add(title);
    Link.Add(link);
    Description.Add(description);
}

Весь мозг ломает индекс в FindChildByXPath("xPath", 0), почему для корректного сбора я должен изменять индекс на +1?
То есть у нас меняется item и мы из этого item под индексом 0 выдергиваем нужные данные по xPath, но нет так не работает, выдергивается только первый результат из выдачи, даже если у нас item от 10 элемента.

Чтобы все заработало и собрать все HtmlElement заголовков должны прописать так
C#:
Развернуть Свернуть Копировать
var i = 0; //Костыль для работы FindChildByXPath
foreach (var item in SearchResultCollection)
{
    var title = item.FindChildByXPath(RESULT_TITLE, i);
    var link = item.FindChildByXPath(RESULT_LINK, i);
    var description = item.FindChildByXPath(RESULT_DESCRIPTION, i);

    Title.Add(title);
    Link.Add(link);
    Description.Add(description);
    i++;
}

Я не понимаю, почему чтобы все корректно работало мы должны менять индекс у нас ведь и так меняется item?!
 
Напишите сами XPath'ы.
 
Напишите сами XPath'ы.
Собрать коллекцию
C#:
Развернуть Свернуть Копировать
var SearchResultCollection = tab.FindElementsByXPath("//li[contains(@class,'item_card')][contains(@data-fast,'1')]");

Работа с коллекцией
C#:
Развернуть Свернуть Копировать
List<HtmlElement> Title = new List<HtmlElement>();
List<HtmlElement> Link = new List<HtmlElement>();
List<HtmlElement> Description = new List<HtmlElement>();

foreach (var item in SearchResultCollection)
{
    var title = item.FindChildByXPath("//span[contains(@class,'organic__title')]", 0);
    var link = item.FindChildByXPath("//div[contains(@class,'organic__path')]", 0);
    var description = item.FindChildByXPath("//span[contains(@class,'TextContent')]", 0);

    Title.Add(title);
    Link.Add(link);
    Description.Add(description);
}
 
Собрать коллекцию
C#:
Развернуть Свернуть Копировать
var SearchResultCollection = tab.FindElementsByXPath("//li[contains(@class,'item_card')][contains(@data-fast,'1')]");

Работа с коллекцией
C#:
Развернуть Свернуть Копировать
List<HtmlElement> Title = new List<HtmlElement>();
List<HtmlElement> Link = new List<HtmlElement>();
List<HtmlElement> Description = new List<HtmlElement>();

foreach (var item in SearchResultCollection)
{
    var title = item.FindChildByXPath("//span[contains(@class,'organic__title')]", 0);
    var link = item.FindChildByXPath("//div[contains(@class,'organic__path')]", 0);
    var description = item.FindChildByXPath("//span[contains(@class,'TextContent')]", 0);

    Title.Add(title);
    Link.Add(link);
    Description.Add(description);
}
У дочерних вроде как точку надо ставить перед первыми двумя слешами
 
  • Оценить
Реакции: sydoow и Dmitriy Ka
У дочерних вроде как точку надо ставить перед первыми двумя слешами

Спасибо, действительно помогло! Я об этом даже и не знал, такая мелочь, а так важна :-)

Получаю нужный результат.
C#:
Развернуть Свернуть Копировать
foreach (var item in SearchResultCollection)
{
    var title = item.FindChildByXPath(".//span[contains(@class,'organic__title')]", 0);
    var link = item.FindChildByXPath(".//div[contains(@class,'organic__path')]", 0);
    var description = item.FindChildByXPath(".//span[contains(@class,'TextContent')]", 0);

    Title.Add(title);
    Link.Add(link);
    Description.Add(description);
}
 
Без точки (означающей текущий элемент), вы нивелируете весь смысл поиска на основе дочернего.
Так же м.б. не лишне избавиться от поиска во всех подэлементах.
 
Regex рулит с хпачем вообще не пойму что делать надо и как его составлять
 
с хпачем вообще не пойму что делать надо и как его составлять
тоже так раньше думал, потом потратил день на изучение, посмотрел видосы на ютубчике, почитал примеры, и теперь пользуюсь только им ... всего лишь день
 
Ах вот оно что, нужно было точку ставить
А я несколько лет думал это глюк ZP: когда перебираешь коллекцию и пытаешься достать из неё элемент через FindChildByXPath -ZP выдавала всегда не то
 
Ах вот оно что, нужно было точку ставить
А я несколько лет думал это глюк ZP: когда перебираешь коллекцию и пытаешься достать из неё элемент через FindChildByXPath -ZP выдавала всегда не то
в каком-то смысле это и есть глюк зп
 
  • Оценить
Реакции: sydoow

Кто просматривает тему: (Всего: 0, Пользователи: 0, Гости: 0)