Поиск div по нескольким элементам с помощью Selenium WebDriver и Python

#python #selenium #selenium-webdriver #xpath #selenium-chromedriver

#python #selenium #selenium-webdriver #xpath #селен-хромовый преобразователь

Вопрос:

 <article>
<div class="inner-article">
<h1><a class="name-link" href="dinamic_URL_1">Tee</a></h1>
<p><a class="name-link" href="dinamic_URL_1">Light Olive</a></p>
</div>
</article>

<article>
<div class="inner-article">
<h1><a class="name-link" href="dinamic_URL_2">Tee</a></h1>
<p><a class="name-link" href="dinamic_URL_2">Navy</a></p>
</div>
</article>

<article>
<div class="inner-article">
<h1><a class="name-link" href="dinamic_URL_3">Tee</a></h1>
<p><a class="name-link" href="dinamic_URL_3">Black</a></p>
</div>
</article>

<article>
<div class="inner-article">
<h1><a class="name-link" href="dinamic_URL_4">sweater</a></h1>
<p><a class="name-link" href="dinamic_URL_4">Light Olive</a></p>
</div>
</article>

<article>
<div class="inner-article">
<h1><a class="name-link" href="dinamic_URL_5">sweater</a></h1>
<p><a class="name-link" href="dinamic_URL_5">Navy</a></p>
</div>
</article>

<article>
<div class="inner-article">
<h1><a class="name-link" href="dinamic_URL_6">sweater</a></h1>
<p><a class="name-link" href="dinamic_URL_6">Black</a></p>
</div>
</article>
 

если возможно, мы должны полагаться на гипертекст («черный», «футболка», «свитер» и т. Д.), Потому что веб-сайт динамический, и тогда они могут удалить такие теги, как h1, p и так далее. большое спасибо за внимание

Предположим, я хочу щелкнуть div черного свитера (примечание: мы находимся в сети на динамическом веб-сайте, и между разделами и вокруг них мы предполагаем, что есть неопределенные другие разделы, поэтому давайте забудем, что div черного свитера является последним).

  1. Мы не можем полагаться на URL-адреса, потому что они динамические.
  2. Мы не можем использовать
 driver.find_element_by_link_text ('sweater'). click ()
 

потому что это щелкнуло бы div Светло-оливкового свитера.

  1. Мы не можем использовать
 driver.find_element_by_link_text ('Black'). click ()
 

потому что это щелкнуло бы по первому div черного тройника.

Как вы можете видеть, что разделы одной и той же статьи идентичны, но вторая ссылка меняется.

Ответ №1:

Попробуйте использовать этот XPATH:

 //div[h1[.="sweater"]][p[.='Black']]
 

Он ищет div, который имеет дочерние узлы h1 и p с нужным текстом.

Если вы не хотите полагаться на определенные теги, используйте символ *, который означает любой элемент:

 //div[*[.='sweater']][*[.='Black']]
 

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

1. это работает отлично, вы действительно выиграли поздравления, но у него есть один недостаток: поскольку сайт динамичен и поддается модификации, я хотел бы полагаться на текст ссылки вместо тегов, таких как h1 h2 h3 <p> и так далее. можете ли вы адаптировать ответ к этой потребности? если это так, я отдам вам коронную победу

2. Готово, посмотрите, это то, что вы имели в виду.

3. пытаюсь использовать //div[a[text()='sweater']][a[text()='Black']] , но это не работает

4. дело в том, что единственная уверенность, которая у нас есть, — это то, что будет гипертекст, в то время как они могут играть в мудаков и удалять любые теги

5. Так что //div[*[.=’sweater’]][*[.=’Black’]] не будет достаточно стабильным? Так нужно ли это с помощью a?

Ответ №2:

Вы можете добиться этого с xpath помощью селекторов в два этапа (я использую здесь lxml.html например, но он должен быть легко преобразован в selenium webdriver .find_element_by_xpath() ):

 from lxml import html

s = """
<article>
<div class="inner-article">
<h1><a class="name-link" href="dinamic_URL_1">Tee</a></h1>
<p><a class="name-link" href="dinamic_URL_1">Light Olive</a></p>
</div>
</article>

<article>
<div class="inner-article">
<h1><a class="name-link" href="dinamic_URL_2">Tee</a></h1>
<p><a class="name-link" href="dinamic_URL_2">Navy</a></p>
</div>
</article>

<article>
<div class="inner-article">
<h1><a class="name-link" href="dinamic_URL_3">Tee</a></h1>
<p><a class="name-link" href="dinamic_URL_3">Black</a></p>
</div>
</article>

<article>
<div class="inner-article">
<h1><a class="name-link" href="dinamic_URL_4">sweater</a></h1>
<p><a class="name-link" href="dinamic_URL_4">Light Olive</a></p>
</div>
</article>

<article>
<div class="inner-article">
<h1><a class="name-link" href="dinamic_URL_5">sweater</a></h1>
<p><a class="name-link" href="dinamic_URL_5">Navy</a></p>
</div>
</article>

<article>
<div class="inner-article">
<h1><a class="name-link" href="dinamic_URL_6">sweater</a></h1>
<p><a class="name-link" href="dinamic_URL_6">Black</a></p>
</div>
</article>
"""

tree = html.fromstring(s)

# step 1 filter out all divs including Black "items"
divs = [el.getparent().getparent() for el in tree.xpath("//a[contains(text(), 'Black')]")]

# step 2 filter our divs from step one to get the "sweater" item
needle = list(filter(lambda div: div.xpath("h1/a[contains(text(), 'sweater')]"), divs))[0]
 

Использование selenium webdriver должно быть примерно таким (не тестировалось, selenium не установлен в моей среде разработки):

 
# step 1 filter out all divs including Black "items"
divs = [el.find_element_by_xpath('..').find_element_by_xpath('..') for el in 
        web_driver.find_element_by_xpath("//a[contains(text(), 'Black')]")]

# step 2 filter our divs from step one to get the "sweater" item
needle = list(filter(
    lambda div: div.find_element_by_xpath("h1/a[contains(text(), 'sweater')]"), divs))[0]
 

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

1. довольно хорошо, проблема в том, что веб-страница находится в Сети (на самом деле она динамическая)

2. Что вы имеете в виду? У вас есть два идентификатора («back» и «sweater»), и решение заключается в фильтрации элементов внутри «динамической веб-страницы» в два этапа: по первому идентификатору, затем по второму.

3. то, что вы сказали, это правильно, но мне нужно получить позицию черного свитера с онлайн-сайта, а не из локальной строки , я не могу загрузить весь исходный код html в строку и выполнить поиск в нем. да, это сработало бы, но это неправильный путь. если вы можете настроить свой ответ, основываясь / полагаясь на URL, тогда вы выиграли

4. если вам нужно выполнить поиск элемента на веб-странице с помощью selenium, я уверен, что вы не будете загружать весь исходный код html в виде строки, а затем выполнять поиск внутри нее. вы хотите напрямую идентифицировать его, и, вероятно, ваш идентификатор фильтров находится на правильном пути

5. Обновлен ответ с использованием selenium webdriver