How do i find element in website that constanly change its label ID deep inside nested DIV?

Viewed 38

I have a site that tracking all our shipment and i would like to use Selenium with Python to fetch all the value into my Excel file. But i'm currently stuck at getting Selenium to work. It will keep reporting back to me that the element is nowhere to be found. The element are also deep deep in the nested of DIV stuff.

Tons of nested, don't know where to start.

at first i tried using

driver.find_element(By.XPATH,"//*[@id='trackItNowForm:j_idt529:0:j_idt535']").text

And quickly found out that part of the ID will constantly changing. (the "idt529:0:j_idt535" part in ID will constantly change to 519, 509 and so on. The zero path will also change based on lenght of data.) Without a clear structure. With that, By.ID is also obviously out of the window.

So now i'm currently out of idea on what to do next. Maybe i didn't put in the corrected syntax? I'm new to Selenium so i'm still confuse on a lot of things (like how XPATH are written and so on.) So an explanation will be appreciated.

3 Answers

You can locate that element by it's TrackingNumber class name. Maybe combined with more known attributes values.
Please try this:

driver.find_element(By.XPATH,"//label[contains(@id,'trackItNowForm') and(contains(@class,'TrackingNumber'))]").text

You may probably will need to add a delay to wait for the element to be visible. In this case WebDriverWait expected conditions is the right way to do it, as following:

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

wait = WebDriverWait(browser, 20)

wait.until(EC.visibility_of_element_located((By.XPATH, "//label[contains(@id,'trackItNowForm') and(contains(@class,'TrackingNumber'))]"))).text

You can try following css selector to identify the element.

option 1:

driver.find_element(By.CSS_SELECTOR,"[id^='trackItNowForm'][id*='id']").text

option 2:

driver.find_element(By.CSS_SELECTOR,"[id^='trackItNowForm'][id*='id'][class*='TrackingNumber']").text

where ^ means starts-with and * contains.

In option 1, it is checking id attribute starts-with trackItNowForm and also contains id

You should understand how xpath works.
For example, for the code you provided:
driver.find_element(By.XPATH,"//div[@class='col-sm-10']/label").text
looks for the first occurrence of a label under a div with the attribute class='col-sm-10' and then takes its text.

Useful links:

Related