Python-Selenium find element based on it sibling element value

Question:

Html code looks like this.

<div>
  <span>Title</span>
  <input value="a">
</div>
<div>
  <span>Price</span>
  <input value="">
</div>

I need to check if Span is price then insert value for Price etc…

Basically I can access to all inputs like

for el in driver.find_elements(by=By.XPATH, value="//input"):
    try:
        if el.parent.span... == 'Price':  #HERE I NEED TO ADD MISSING PART
           el.send_keys('10')
    except:
        pass

But then I can’t determine upper node value.

Also tried with :

driver.find_element(by=By.XPATH, value="//input/preceding-sibling::span[contains(.,'Price')]")

Like this I’m able to locate Span element but I need to insert price in INPUT.

Since this is only snippet from a way bigger code where class names positions etc. are dynamically generated. I need to go this way.

Asked By: PyDeveloper

||

Answers:

You can locate the input element based on it span sibling text content value as following:

"//div[contains(.,'Price')]//input"

(There are more ways to do that).
So your Selenium code can be as following:

driver.find_element(By.XPATH, "//div[contains(.,'Price')]//input").send_keys('10')

In case <span>Price</span> is a direct child of the parent div we can make the locator more precise, as following:

driver.find_element(By.XPATH, "//div[./span[contains(text(),'Price')]]//input").send_keys('10')

Briefly explanations:
With XPath we can locate elements by any it attributes.
Here we can locate the parent div based on the fact it contains a direct span child element containing the Price text.
So, span[contains(text(),'Price')] will match a span with Price text content while //div[./span[contains(text(),'Price')]] literally says:
"Find somewhere // an element with div tag name so that inside it (this is why a dot . is used there) a direct child / is span whos text content is Price".
Once we have this div we can find it input child by //input.
So simple.

Answered By: Prophet