Как выбрать элемент в Selenium из списка?

Проблема заключается в том, что не получается зацепиться за элемент в списке, а именно нужно нажать на ссылку “Моя страница”
Я попытался зацепиться за id, за класс, за текст в линке, за xpath - не выходит.

Код самого элемента

<li id="l_pr" class=""><a href="https://vk.com/32444224224" onclick="return nav.go(this, event, {noback: true, params: {_ref: 'left_nav'}});" class="left_row">
    <span class="left_fixer">
      <span class="left_count_wrap fl_r left_void"><span class="inl_bl left_count_sign">0</span></span>
      <span class="left_icon fl_l"></span>
      <span class="left_label inl_bl">Моя страница</span>
    </span>
  </a>
  <div class="left_settings" onclick="menuSettings(0)">
  <div class="left_settings_inner"></div>
</div>
</li>

Весь мой код выглядит так

from selenium import webdriver

from selenium.webdriver.support.ui import Select	#DOM Select

import time

browser = webdriver.Firefox()

browser.get('https://vk.com/')

textarea = browser.find_element_by_css_selector('#index_email')

textarea.send_keys('')

textarea = browser.find_element_by_css_selector('#index_pass')

textarea.send_keys('')

submit = browser.find_element_by_css_selector('#index_login_button')

submit.click()

#user_name = browser.find_element_by_css_selector('#l_pr')
user_name = browser.find_element_by_xpath('//a[@class='left_row']')

user_name.click()

Добрый день, попробуй такой xpath

//*[contains(@onclick,'left_nav')]
либо  //li[.//*[contains(@onlick,'left_nav')]] - В данном случае найдется li с дочерним элементом у которого атрибут onlick содержит left_nav

потом нажми на на этот элемент, а потом уже ищи элемент который тебе нужен.

//*[contains(text(),'Моя страница')]

либо от предыдущего элемента

element.findElementByXpath(".//*[contains(text(),'Моя страница')]")

XPATH - “//span[@class=‘left_label inl_bl’][contains(.,‘Моя страница’)]” - еще перед поиском можно подождать секунду/две.

Ну подождать это хорошо конечно, но лучше подождать конкретно отображение элемента, просто так паузы в тестах лучше не делать…

а чем пауза может навредить?

у нас на соседнем проекте паузы по 10-15 секунд, соответственно банальная авторизация занимает минуты 2

тут как только начнёшь пользоваться sleep-ами, так сразу соблазн пихать из повсюду без разбора

1 лайк

у Cелениума есть wait untill, вообще не нужно ничего придумывать

Спасибо - открыли Америку:) это тоже самое практически только без условий

Wait Untill тоже самое что Thread.Sleep, вы это имеете ввиду?

нет конечно :slight_smile: … я просто в конкретном случае не вижу проблем поставить wait c запасом

если другие варианты есть, а вы делаете задержку, то это проблема :wink:

а чем лучше wait until просто wait, и какая проблема может появиться в конкретном случаи? Подскажите.

Например вы ставите
Thread.Sleep(3000) - 3 секунды
или
wait.Until(condition) - и устанавливаете максимальное ожидание 30 сек с периодом опроса 100 миллисекунд

Допустим в среднем все загружается за одну секунду
Какие проблемы в первом случае:

  1. Мы всегда ждем лишних 2 секунды, в 150 тестах это будет 5 минут что не так уж мало
  2. Тест может упасть если загрузка значительно замедлится

Что дает нам Wait Until

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

обычный wait вы ставите по своим субъективным соображениям

а если ширина канала уменьшится? будете wait увеличивать?

Спасибо! Познавательно:+1: иногда 5 минут не играют роли :slight_smile:

После создания браузера воткните implicitlyWait будет ждать 25 пока элемент не появится.
Если появится быстрее сразу начнет работу.

В особенных случаях перед поиском элемента можно сделать ожидалку меньше, а потом вернуть на дефолтное

driver.manage().timeouts().implicitlyWait(“25”,TimeUnit.SECONDS);

Пример:

try{
  driver.manage().timeouts().implicitlyWait("2",TimeUnit.SECONDS);
  driver.findElement(By.xpath("//div[*]")
}
catch(Exception e){
 throw e;
}
finally{
 driver.manage().timeouts().implicitlyWait("25",TimeUnit.SECONDS);
}

либо при поиске юзать wait.until