Marc vT
Marc vT

Reputation: 506

Finding xpath siblings after declaring a variable with find_elements

I start by trying to find all menu items on a site by selecting them with a .find_elements_by_xpath. This works fine

(The buttons are either text or an image).

Then I want to loop through each of these elements and return either the text between the tags or the src of the image of a span tag which preceeds the tag inbetween which there is text.

Returning the text works fine but I am unable to return the src. I am having trouble building an xpath which roots from the current iteration of the loop. What I am left with is either an 'unable to locate' or I return the first menu image over and over again.

Here is the code I currently have running (note I am unable to give out the URL to the site):

browser = webdriver.Chrome(...)
menu = browser.find_elements_by_xpath('//td[@onmouseover]')
for menu_part in menu:
try:
    if len(menu_part.text) < 2:
        menu_button = menu_part.find_element_by_xpath(
                    '/span[@class="ThemeOfficeMainFolderText"]/preceding-sibling::span/img').get_attribute('src')
    else:
        menu_button = menu_part.text
    print menu_button
except Exception as e:
    print e
    pass

I am unsure if the syntax is completely correct/ if I can use the currently iterated element as the 'root' of my find_element function (menu_part.find_element_by_xpath) Also, there is no way to further specify the tags with attributes because all menu items have identical attributes. Lastly, the following code returns the first image in the menu.

menu_button = browser.find_element_by_xpath(
                    '//span[@class="ThemeOfficeMainFolderText"]/preceding-sibling::span/img').get_attribute('src')

Therfore, I am relatively confident the code following "span[@class... " works fine, the issue is the preceding code.

I am hopeful that there is a simple solution and that I made a mistake while writing the xpath, but I am completely out of ideas at the moment...

EDIT:

here is the basic html structure I am dealing with

<td class="ThemeOfficeMainItem" onmouseover="ItemMouseOverOpenSub ()">
    <span class="ThemeOfficeMainFolderLeft">
        <img src="img1.png"></span>
    <span class="ThemeOfficeMainFolderText">TEXT</span>
    <span class="ThemeOfficeMainFolderRight">&nbsp;</span>
</td>
<td class="ThemeOfficeMainItem" onmouseover="ItemMouseOverOpenSub ()">
    <span class="ThemeOfficeMainFolderLeft">
        <img src="img2.png"></span>
    <span class="ThemeOfficeMainFolderText"></span>
    <span class="ThemeOfficeMainFolderRight">&nbsp;</span>
</td>

Upvotes: 1

Views: 240

Answers (1)

Andersson
Andersson

Reputation: 52685

If you want to search for span starting from previously defined parent element menu_part, then you should use

./span[@class="ThemeOfficeMainFolderText"]/preceding-sibling::span/img

Note the dot at the beginning of XPath that points to current (menu_part) element

Update

As for the logic of your code, try below:

browser = webdriver.Chrome()
browser.get(URL)
menu = browser.find_elements_by_xpath('//td[@onmouseover]')
for menu_part in menu:
    text_span = menu_part.find_element_by_xpath('./span[@class="ThemeOfficeMainFolderText"]')
    if not text_span.text:
        menu_button = menu_part.find_element_by_xpath('./span[@class="ThemeOfficeMainFolderText"]/preceding-sibling::span/img').get_attribute('src')
    else:
        menu_button = text_span.text
    print menu_button

Upvotes: 1

Related Questions