Home > front end >  XPATH target div and image in loop?
XPATH target div and image in loop?

Time:12-10

Here's the document struvture:

<div >
<div>
 <div >
   <div >
    <div >
     <img  src="https://www.testimage.com/test.jpg"/>
     <span></span>
    <span>test</span>
    </div>
   </div>
  </div>
</div>
<div>
 <div >
   <div >
    <div >
     <img  src="https://www.testimage.com/test.jpg"/>
     <span></span>
    <span>test</span>
    </div>
   </div>
  </div>
</div>

</div>

not sure the best way to do this but hoping someone can help. I have a for loop that grabs all the divs that precede a div with class "feed-shared-update-v2". This works:

elements = driver.find_elements(By.XPATH, "//*[contains(@class, 'feed-shared-update-v2')]//preceding::div[1]");

I then run a for loop over it:

for card in elements:

however i'm having trouble trying to target the img and the second span in these for loops. I tried:

for card in elements:
  profilePic = card.find_element(By.XPATH, ".//following::div[@class='update-components-actor']//following::img[1]").get_attribute('src')
  text = card.find_element(By.XPATH, ".//following::div[@class='update-components-text']//following::span[2]").text

but this produces a error saying:

selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":".//following::div[@class='update-components-actor']//following::img[1]"}

so I'm hoping someone can point me in the right direction as to what i'm doing wrong. I know its my xpath syntax and i'm not allowed to chain "followings" (although even just trying .//following doesn't work, so is ".//" not the right syntax?) but i'm not sure what the right syntax should be, especially since the span does not have a class. :(

Thanks!

CodePudding user response:

I guess you are overusing the following:: axis. Simply try the following (no pun intended):
For your first expression use

//*[contains(@class, 'feed-shared-update-v2')]/..

This will select the parent <div> of the <div >. So you will select the whole surrounding element.
To retrieve the children you want, use these XPaths: .//img/@src and .//span[2]. Full code is

for card in elements:
  profilePic = card.find_element(By.XPATH, ".//img").get_attribute('src')
  text = card.find_element(By.XPATH, ".//span[2]").text

That's all. Hope it helps.

CodePudding user response:

It seems in the span that there is not such class of div called: update-components-text

did you mean: update-components-actor?

Im not such a fan of xpath, but when i copied your html and img selector, it did find me 2 img, maybe you are not waiting for the element to load, and then it fails? try using implicit/explicit waits in your code.

I know you are using xpath, but concider using css

This might do the trick:

.feed-shared-update-v2 span:nth-of-type(2)

And if you want a css of the img:

.feed-shared-update-v2 img
  • Related