Skip to content
Advertisement

Stale element: iterating through webelement list python

I’m using selenium for the first time to get some information about a fantasy soccer game I play with my friends (we have a competition). I’m facing issues iterating through a list of webelements. Apparently they become stale. Here’s some code and details:

I was able to get to the competition’s page by myself. This page has cards for every team in the competition and they look like this

<span class="cartola-card-thin__nome__time">TEAM1</span>

When clicked, those cards lead to that team’s page. This page contains a dropdown menu that looks like this

<span class="cartola-dropdown-bg__botao cartola-dropdown-bg-botao-rodada-id cartola-dropdown-bg__botao--aberto" ng-class="'cartola-dropdown-bg-botao-' + name"></span>

and this menu contains a div for each round of the competition. It looks like this

<div ng-if="!hasDescription" class="cartola-dropdown-bg__selecao" ng-bind="item.label">rodada 25</div>

When clicked, each div loads that specific team’s formation, and its points during that round. The points are shown on the page like this:

<div class="cartola-time-adv__pontuacao pont-positiva" ng-class="{'pont-positiva': ctrl.timeService.dadosTime.pontos > 0,
                    'pont-negativa': ctrl.timeService.dadosTime.pontos < 0}" ng-bind="ctrl.timeService.dadosTime.pontos != null ? ctrl.timeService.dadosTime.pontos : ''">78.17</div>

My goal: I want to gather each team’s points during each one of the rounds in a dict[’round’] = points.

What I’ve tried already: I’ve tried to keep the teams in a list by doing

teams = browser.find_elements_by_class_name("cartola-card-thin__nome__time")

Then, for each team in teams I’d click on it. When on that page I’d find each round like this

rounds = browser.find_elements_by_class_name("cartola-dropdown-bg__selecao")

Then, for each round in rounds I’d click on it and get that round’s points.

The problem: those loops where I iterate through teams and rounds are not working because apparently those webelements become stale after the whole process inside the loop (clicking, etc)

How can I approach this problem?

Advertisement

Answer

Angular drop down elements are rebuild in runtime. After drop down is collapsed – previously found drop down item is no longer an element of DOM. It is added to DOM one more time, when drop down is expanded again – but it is not the same element for WebDriver (even if it can be found with the same locator).

So, you’re following this logic:

  1. Expand drop down
  2. Get drop down elements ->
teams = browser.find_elements_by_class_name("cartola-card-thin__nome__time")
  1. Do something for each team -> here, I suppose, that drop down is collapsed. So found WebElements are no longer in DOM -> stale element exception

What you have to do?

teamsCount = len(teams);
teamIndexes = range(teamsCount)
for(i in temIndexes)
    team = driver.find_element(locator_that_usesTeamIndex)
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement