Home > OS >  Distinguishing between the same web elements with Python Selenium based on relates
Distinguishing between the same web elements with Python Selenium based on relates

Time:09-19

After third attempt of solving this problem, I am unable to finalize this on my own. I would appreciate, if someone would like to share their thoughts on the following issue.

Let us assume, we have such kind of HTML structure:

<div ></div>
    <div ></div>
        <h3 >HEADER NUMBER ONE<h3>
    <div ></div>
        <div >IO field</div>
            <input ></input>
            
<div ></div>
    <div ></div>
        <h3 >HEADER NUMBER TWO<h3>
    <div ></div>
        <div >IO field</div>
            <input ></input>

My intention is to identify an input element that belongs to the second panel.

Based on reliability check, when I have hardcoded XPATH gathered directly from the browser, sometimes wrong element is being identified (I assume that there are many scripts running when the page is being loaded, which impacts the reliability and stability). Therefore I would like to distinguish between elements based on the h3, which are the one and only difference between objects.

How can I do it?

When identifying elements one by one (so first the title, then its parent, and then moving down to the input), I receive an "element not interactable" exception which is not dependent from the time.

I am thinking of something like:

find //input[@class='input'] where one of ancestors contains /div/h3 which contains(text(), 'HEADER NUMBER TWO')

Obviously, I did not found any working solution for that, despite I spent more than a week with that.

Is it doable at all? If so, could you suggest me something, please? The structure in real is a little bit more complex, but I need just a pattern, hint, or clue.

Greetings!

CodePudding user response:

You can locate the parent panel element based on it's child h3 with the desired title and then to locate the input element inside it.
The XPath to do so can look like the following:

"//div[@class='panel' and(.//h3[contains(.,'HEADER NUMBER ONE')])]//input"

Or even

"//div[@class='panel' and(contains(.,'HEADER NUMBER ONE'))]//input"

The selenium command using that XPath can look like:

driver.find_element(By.XPATH, "//div[@class='panel' and(contains(.,'HEADER NUMBER ONE'))]//input")

More explanations
The XPath

"//div[@class='panel' and(.//h3[contains(.,'HEADER NUMBER ONE')])]//input"

literally means:
Find element with div tag and class attribute value panel and having some child element inside it (this is .// comes for) containing HEADER NUMBER ONE text content.
Inside the above div element find input child element.

CodePudding user response:

In Selenium you can find a set of elements:

inputs = driver.find_elements(By.CSS, 'input[]')
input_2 = inputs[1]

The input you need is the 2nd element in the list

  • Related