Selenium Staleelementreferenceexception Problems with Python

Asked

Viewed 97 times

0

I am new here in the forum,I hope you can help me, I am creating an application with Selenium using python to collect documents on a specific site. documents are uploaded to download via javascript and then my loop only picks up the first document and when trying to catch the second error gives Staleelementreferenceexception, below follows a sample of html and the code block I am using. Note: I am using python 3.6 and Chrome driver. I want to get only the links from the second column of the table.

    <table id="GRDDOCS" border="0" cellpadding="0" cellspacing="0" width="780" class="Texto" style="z-index:100;width:780;height:20;">
  <tbody><tr>
   <tr>
    <td valign="middle" align="left" nowrap="" width="90" class="texto1">&nbsp;</td>
    <td valign="middle" align="left" nowrap="" width="300" class="texto1">
      <a href="#" onclick="return SubmitClickConfirm('GRDDOCS','6_1', true, '')"></a>
      <a href="javascript:void(0)" onclick="LINK11; return false" id="LINK11" name="LINK11" style="z-index:100;font-weight:bold;font-size:9px;text-decoration:none;color:#FF0000;">documento.jpg</a>
    </td>
    <td valign="middle" align="left" nowrap="" width="170" class="texto1">
      <a href="javascript:void(0)" onclick="LINK12; return false" id="LINK12" name="LINK12" style="z-index:100;">Excluir</a>
    </td>
    <td valign="middle" align="left" nowrap="" width="170" class="texto1">&nbsp;</td>
    <td></td>
  </tr>
  <tr>
    <td valign="middle" align="left" nowrap="" width="90" class="texto2">&nbsp;</td>
    <td valign="middle" align="left" nowrap="" width="300" class="texto2">
      <a href="#" onclick="return SubmitClickConfirm('GRDDOCS','7_1', true, '')"></a>
      <a href="javascript:void(0)" onclick="LINK13; return false" id="LINK13" name="LINK13" style="z-index:100;font-weight:bold;font-size:9px;text-decoration:none;color:#FF0000;">documento02.jpg</a>
    </td>
    <td valign="middle" align="left" nowrap="" width="170" class="texto2">
      <a href="javascript:void(0)" onclick="LINK14; return false" id="LINK14" name="LINK14" style="z-index:100;">Excluir</a>
    </td>
    <td valign="middle" align="left" nowrap="" width="170" class="texto2">&nbsp;</td>
    <td></td>
  </tr>
  <tr>
    <td valign="middle" align="left" nowrap="" width="90" class="texto1">&nbsp;</td>
    <td valign="middle" align="left" nowrap="" width="300" class="texto1">
      <a href="#" onclick="return SubmitClickConfirm('GRDDOCS','8_1', true, '')"></a>
      <a href="javascript:void(0)" onclick="LINK15; return false" id="LINK15" name="LINK15" style="z-index:100;font-weight:bold;font-size:9px;text-decoration:none;color:#FF0000;">documento03.jpg</a>
    </td>

Code block:

    if driver.find_element_by_id("GRDDOCS"):
   table_id = driver.find_element_by_id("GRDDOCS")
   rows = table_id.find_elements(By.TAG_NAME, "tr")
   for row in rows:
     col = row.find_elements(By.TAG_NAME, "td")[1]  
       if col.find_elements(By.TAG_NAME, "a"):
         prop = driver.find_element_by_link_text(col.text)
         driver.execute_script("arguments[0].click();", prop)
         time.sleep(5)

Good morning guys, I made the following changes, I added an explicit wait after picking up the first document to check if the elements return to the page and print if I find and try to get the document again but without success, can anyone help me? follows updated code below:

if driver.find_element_by_id("GRDDOCS"):
  table_id = driver.find_element_by_id("GRDDOCS")
  rows = table_id.find_elements(By.TAG_NAME, "tr")
  for row in rows:
      col = row.find_elements(By.TAG_NAME, "td")[1]
      if col.find_elements(By.TAG_NAME, "a"):
          prop = self.driver.find_element_by_link_text(col.text)
          self.driver.execute_script("arguments[0].click();", prop)
          element = WebDriverWait(self.driver, 120).until(
                 EC.presence_of_element_located((By.ID, "GRDDOCS"))
               )
          time.sleep(5)
          if element.is_displayed:
              self.logger.info(f"Elemento visível: 
               {element.is_displayed()}")
              self.driver.execute_script("arguments[0].click();", prop)

1 answer

0

This error only occurs in two situations:

  1. When the element you are referencing is removed from the page, via javascript or other method.

    That’s the most common situation. Something occurs on the page, arising from running dynamic code in javascript or user interaction, and the element is no longer there. The part where it is may have been reloaded, or the user may have navigated to another page. The element may also have been replaced, via javascript code, by another element with the same ID or attributes.

  2. When the element is no longer in the DOM tree.

    Certain dynamic pages use methods to simulate tabs in a web application. One of the ways to do this is to create divs for each tab, but only attach one of the divs to the DOM and store the rest in variables. In this case, it may happen that your script refers to an object that is no longer attached to the DOM tree (that is, it is no longer a child of document.document).

In both cases there is no way to reconnect the object and work with it. You have to discard the object and fetch it again in the DOM, through one of the functions of the element localization Selenium (find_elements for example).

Browser other questions tagged

You are not signed in. Login or sign up in order to post.