0

I am getting regurarly a lot of mails which contains some filenames and their IDs (e.g. FILENAME_VERSION_ID). Based on these IDs I have to log in on a portal and download every file separately. So I have made a script in Python based on Selenium to download these files automatically.

My program works the following way:

The script extracts the IDs of these file in a txt called ID.txt.

Then, I have used a for loop to read every line of the ID file till it ends.

So what I want now is to find the elements from ID.txt based on partial text in the full filename (the id of the filename).

with open('ID.txt') as f:
for line in f:
    driver.find_element_by_xpath("//*[contains(@id,'%s')]" % str(line))
    pyautogui.press('enter')
    driver.find_element_by_xpath("//*[text()='ro']").click()
    driver.find_element_by_xpath("//*[contains(@id,'%s')]" % str(line)).click()
    driver.find_element_by_xpath("//*[text()='export']").click()
    if 'str' in line:
        break

Apparently selenium cannot find the element for this line of code

driver.find_element_by_xpath("//*[contains(@id,'%s')]" % str(line))

One element on the site I want to click looks the following way:

<div index="0" aria-busy="false" aria-checked="false" aria-disabled="false" data-head="true" aria-label="09251561001.09251561001.1.31873860875, folder" aria-selected="false" class="option grid-row" role="option" id=":DOMLT_ELISYS:export:09251561001.09251561001.1.31873860875">
   <div class="name-data icon folder" id="id1027">
      <div class="progressbar" role="progressbar" aria-hidden="true" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">
         <div class="fill" role="presentation" style="width: 0%;"></div>
         <div class="fill" role="presentation" style="width: 0%;"></div>
      </div>
      <a class="name-text" href="#">
      <span>09251561001.09251561001.1.31873860875</span>
      </a>
   </div>
   <div id="cellId1028" class="date-data"></div>
   <div id="cellId1029" class="size-data"></div>
</div>

In my ID.txtfile are stored only the last numbers after dot (31873860875, in this specific case).

I have tried a lot of possibilities but it is not working. I get the following error:

raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//*[contains(@id,'31873860875
')]"}

What am I not doing right here? It is there an alternative way to select/click this element on the site?

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352

3 Answers3

0

This happens a lot of time when the element is not loaded and you are trying to locate it. You can use waits to resolve this issue so that proper loading of DOM takes place . https://selenium-python.readthedocs.io/waits.html

One of the following will be useful

  • presence_of_element_located
  • visibility_of_element_located
  • presence_of_all_elements_located
  • element_to_be_clickable
Vishesh Mangla
  • 664
  • 9
  • 20
0

WebDriverWait should help you in this case:

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

botton_to_click = WebDriverWait(driver, 10).until(EC.element_to_be_clickable, ((By.XPATH,"//*[text()='ro']")))
botton_to_click.click()

I believe after the program waitsenough for clicking text()='ro', it will be able to click "//*[contains(@id,'%s')]". If not, you can do the same botton_to_click thing for the following XPaths.

driver.find_element_by_xpath("//*[contains(@id,'%s')]" % str(line)).click()
driver.find_element_by_xpath("//*[text()='export']").click()
Cagri
  • 307
  • 3
  • 13
0

You were close enough. The text 31873860875 is with in a <span> tag and is the text.

So to locate the element you need to induce WebDriverWait for the visibility_of_element_located() and you can use either of the following Locator Strategies:

  • Using XPATH:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, ""//a[@class='name-text']/span[contains(.,'%s')]" % str(line)))).click()
    
  • Note : You have to add the following imports :

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352