Selenium просматривает класс и определяет, сколько элементов в классе, наконец выполняет действие над всеми найденными элементами. - PullRequest
1 голос
/ 17 февраля 2020

Мне нужно взаимодействовать с элементами в классе, но число элементов в этом классе меняется каждый раз, когда я запускаю скрипт.

Чтобы дать вам контекст, веб-сайт представляет собой календарь, где мне нужно выбрать день, который я буду использовать в качестве шаблона для своей работы. Каждый раз, когда я запускаю скрипт (Ежемесячно), веб-страница с календарем обновляется и отображает текущий месяц, поэтому Selenium выбирает тот же день, что и в предыдущем месяце. Но каждый месяц день выбора Selenium имеет различное содержание, и количество элементов меняется каждый месяц. В настоящее время, например, сценарий написан для взаимодействия с 5 элементами, но в следующем месяце он не будет работать, потому что выбранный день будет иметь различное количество элементов. Поэтому каждый месяц мне приходится вручную менять скрипт, чтобы взаимодействовать с правильным количеством элементов.

Вот пример структуры элементов сайта:

<ul class="list-unstyled tags-list grid_9">
     <li><!-- react-text: 185 -->Text<!-- /react-text --><i data-id="0" class="icon-cancel pointer icon12 
      ml5px error"></i></li>
     <li><!-- react-text: 188 -->Text<!-- /react-text --><i data-id="1" class="icon-cancel pointer icon12 
      ml5px error"></i></li>
     <li><!-- react-text: 191 -->Text<!-- /react-text --><i data-id="2" class="icon-cancel pointer icon12 
      ml5px error"></i></li>
</ul>

Итак, количество элементов что мне нужно взаимодействовать внутри класса 'list-unstyled tags-list grid_9' всегда меняется. Элементы с идентификаторами "0", "1" и "2". Иногда может быть 4 элемента с идентификаторами «0», «1», «2», «3», а иногда есть 2 элемента и т. Д. c.

Я пытался выяснить, как написать скрипт, в котором Selenium просматривает этот класс '' list-unstyled tags-list grid_9 ', посмотрите, сколько там элементов и выполняет -

driver.find_element_by_(xpath,class,id whatever).click()

на всех найденных там элементах.

ОБНОВЛЕНИЕ: Итак, я попробовал этот код:

tab = driver.find_element_by_css_selector('#postForm > div:nth-child(3) > ul.list-unstyled.tags-list.grid_9')
    hashs = tab.find_elements_by_tag_name('li')
    for element in hashs:
        element.find_element_by_tag_name('i').click()

И он дал мне эту ошибку:

stale element reference: element is not attached to the page document

Ответы [ 3 ]

1 голос
/ 18 февраля 2020

Я думаю, вы очень близки к достижению своей цели. Просто попробуйте щелкнуть JS.

tab = driver.find_element_by_css_selector('#postForm > div:nth-child(3) > ul.list-unstyled.tags-list.grid_9')
hashs = tab.find_elements_by_tag_name('li')
for element in hashs:
    x_element=element.find_element_by_tag_name('i')
driver.execute_script("arguments[0].click();", x_element)

ИЛИ

Подождите, пока элемент станет активным, а затем нажмите.

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

tab = driver.find_element_by_css_selector('#postForm > div:nth-child(3) > ul.list-unstyled.tags-list.grid_9')
hashs = tab.find_elements_by_tag_name('li')

number_of_buttons = len(hashs)
for x in range(number_of_buttons):

   button = WebDriverWait(driver, 50).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "#postForm > div:nth-child(3) > ul.list-unstyled.tags-list.grid_9 > li:nth-child(" + str(x+1) + ") > i")))
    button.click()
1 голос
/ 17 февраля 2020

Вы можете использовать тот факт, что элемент также имеет все методы find_elem..., которые есть у веб-драйвера, но только в контексте этого элемента, который работает для вас следующим образом:

from selenium import webdriver

driver = webdriver.Firefox()
calendar_day_element = driver.find_element_by_css_selector('ul.list-unstyled.tags-list.grid_9')
day_events = calendar_day_element.find_elements_by_tag_name('li')

Теперь day_events - это список всех li элементов в выбранном дне, и вы можете перебирать его.

Редактировать: Учитывая ваши потребности щелкнуть по элементу <i>, я изменил последнюю строку на:

day_events = calendar_day_element.find_elements_by_css_selector('li > i')

Средство выбора li > i дает мне все <i> элементы, которые являются прямыми потомками <li> элемента

0 голосов
/ 18 февраля 2020

Ссылка на устаревший элемент Исключение происходит, если страница обновляется или элемент изменяется на странице (также обновляется или исчезает). В вашем случае это, скорее всего, происходит либо с tab, hash, либо со вторым element (не могу сказать, не увидев страницу).

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

tab = driver.find_element_by_css_selector('#postForm > div:nth-child(3) > ul.list-unstyled.tags-list.grid_9')
hashs = tab.find_elements_by_tag_name('li')

for i in range(len(hashs)):
    tab = driver.find_element_by_css_selector('#postForm > div:nth-child(3) > ul.list-unstyled.tags-list.grid_9')
    element = tab.find_elements_by_tag_name('li')[i]
    element.find_element_by_tag_name('i').click()

Надеюсь, это поможет. Удачи!

...