xpath - берется только первый по счету элемент

nik-n

Client
Регистрация
05.11.2016
Сообщения
242
Благодарностей
20
Баллы
18
https://yandex.ru/search/ads?text=автосервис москва
Нужно по очереди пройтись по тем результатам выдачи которые содержат ссылку "Контактная информация" и скопировать доменное имя.
Но еще не успел дойти до того как взять доменное имя и на тесте поиска ссылок "Контактная информация" возникла загвоздка:
XPath не хочет искать элементы кроме первого по счету.

PHP:
string btnText = "Контактная информация";
string count = project.Variables["countContactsXpath"].Value;
string xpath_exp = "//a[contains(text(), '" + btnText + "')][" + count + "]";
string action_ev = "get|href";
string set_action = "";
return CommonCode.FindElementAndExecuteAction(instance, xpath_exp, action_ev, set_action);
если count =1
то все ок и берется первый элемент

если count больше 1
тогда
Сбой - элемент не найден

но там их еще дохрена!!!

помогите уж пжлст
 

Вложения

budora

Client
Регистрация
13.08.2012
Сообщения
831
Благодарностей
556
Баллы
93
Твой проект сразу криво компилится
Переписал всё в новый проект только тогда собрало.
 

ТРОН

Client
Регистрация
31.07.2016
Сообщения
336
Благодарностей
381
Баллы
63
Данный код кладет все домены в список "links".
Код:
var links = instance.ActiveTab.FindElementsByXPath("//li/div/div/div/a/b");
if (links.Count==0)    throw new Exception("Совпадений не найдено");
foreach (var link in links.Elements)
{
    var domen = link.GetAttribute("innerhtml");
    project.Lists["links"].Add(domen);
}
 

nik-n

Client
Регистрация
05.11.2016
Сообщения
242
Благодарностей
20
Баллы
18
Данный код кладет все домены в список "links".
Код:
var links = instance.ActiveTab.FindElementsByXPath("//li/div/div/div/a/b");
if (links.Count==0)    throw new Exception("Совпадений не найдено");
foreach (var link in links.Elements)
{
    var domen = link.GetAttribute("innerhtml");
    project.Lists["links"].Add(domen);
}
Вот только нужны домены только тех у кого есть ссылка "Контактная информация"
 

ТРОН

Client
Регистрация
31.07.2016
Сообщения
336
Благодарностей
381
Баллы
63
Вот только нужны домены только тех у кого есть ссылка "Контактная информация"
Они и так там все с "контактной информацией", если нет авторизации в почте.

upload_2018-2-14_13-14-45.png

upload_2018-2-14_13-15-52.png
 

LaGir

Client
Регистрация
01.10.2015
Сообщения
227
Благодарностей
927
Баллы
93
если count больше 1
тогда
Сбой - элемент не найден
Синтаксис неправильный для этого случая, необходимо в круглые скобки основную часть пути поместить:
C#:
string xpath_exp = "(//a[contains(text(), '" + btnText + "')])[" + count + "]";
 
  • Спасибо
Реакции: nik-n

ssXXXss

Client
Регистрация
23.12.2014
Сообщения
7 379
Благодарностей
2 041
Баллы
113
Твой проект сразу криво компилится
Переписал всё в новый проект только тогда собрало.
у меня вчера один из проектов такую ошибку выдавал, AutoSave, ничего не менял, просто в РМ ни с чего началась такая строка сыпаться
 

nik-n

Client
Регистрация
05.11.2016
Сообщения
242
Благодарностей
20
Баллы
18
Синтаксис неправильный для этого случая, необходимо в круглые скобки основную часть пути поместить:
C#:
string xpath_exp = "(//a[contains(text(), '" + btnText + "')])[" + count + "]";
Супер! Так и думал что надо что то во что то завернуть, но нигде в сети синтаксиса с примером не нашел ))
Большое спасибо!
 

nik-n

Client
Регистрация
05.11.2016
Сообщения
242
Благодарностей
20
Баллы
18
Синтаксис неправильный для этого случая, необходимо в круглые скобки основную часть пути поместить:
C#:
string xpath_exp = "(//a[contains(text(), '" + btnText + "')])[" + count + "]";
Я лох! Остальное не получается найти. Надо на 5 уровней вверх , потом опуститься в b и взять у него innerHtml, но что то видимо опять с синтаксисом не так у меня.
Пишу так
PHP:
string xpath_exp = "(//a[contains(text(), '" + btnText + "')])[" + count + "]/../../../../../div[1]/div[1]/a[1]/b[1]";
Итог опять тот же, элемент не найден )
 

Вложения

LaGir

Client
Регистрация
01.10.2015
Сообщения
227
Благодарностей
927
Баллы
93
Надо на 5 уровней вверх , потом опуститься в b и взять у него innerHtml, но что то видимо опять с синтаксисом не так у меня.
Подобными алгоритмами в XPath точно не стоит пользователя. Например, в приведенном пути зависимость аж от 10 элементов и их взаимосвязи, хотя бы 1 изменится - путь ломается. А так как объявления Директа разные (разная степень "заполненности"), структура их различается - такие пути сразу же непригодные.

Лучше искать через тот элемент, который содержит и то, что нужно найти, и то, через что ищем. В нашем случае берём элемент с тегом li, который содержит всё объявление целиком:
2018-02-15_15-19-28.png


Путь такой:
Код:
//li[descendant::a[contains(text(), 'Контактная информация')]]
"Идём к элементу li, у которого есть потомок a с текстом 'Контактная информация'"

Далее от этого элемента идём к тегу b, который содержит текст ссылки. Добавляем к первому пути хвост:

2018-02-15_15-19-56.png


Код:
/descendant::b[parent::a[contains(@class,'path')]]
"Идём к элементу b, у которого "родитель" (элемент выше по уровню) - ссылка a со словом path в названии класса"

Теперь можно поместить весь этот путь в скобки и обращаться к конкретным ссылкам через индекс.
C#:
string xpath_exp = "(//li[descendant::a[contains(text(), '" + btnText + "')]]/descendant::b[parent::a[contains(@class,'path')]])[" + count + "]";
 
  • Спасибо
Реакции: Mihalich и nik-n

nik-n

Client
Регистрация
05.11.2016
Сообщения
242
Благодарностей
20
Баллы
18
Теперь можно поместить весь этот путь в скобки и обращаться к конкретным ссылкам через индекс.
C#:
string xpath_exp = "(//li[descendant::a[contains(text(), '" + btnText + "')]]/descendant::b[parent::a[contains(@class,'path')]])[" + count + "]";
Мда, Xpath я люблю тебя! )
LaGir, респект! :az:
 

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