2

I am by no ways a developer. I get by by google, but this issue has a depth I do not understand.

If you can explain what I am lacking in programming knowledge it'd be appreciated.

With powershell I can get all .Text from whatever div I choose. However I cannot figure out how to find the Text from a within a div whose .Text is "abc"

$allGames.Text contains all the game titles, so far so good:

[System.Reflection.Assembly]::LoadFrom("{0}\WebDriver.dll" -f $PathToFolder)
    if ($env:Path -notcontains ";$PathToFolder" ) {
        $env:Path += ";$PathToFolder"
    }
    $ChromeOptions = New-Object OpenQA.Selenium.Chrome.ChromeOptions
    $ChromeOptions.AddArgument('start-maximized')
    $ChromeDriver = New-Object OpenQA.Selenium.Chrome.ChromeDriver($ChromeOptions)
           
    $ChromeDriver.Url = $uri
    #sometimes site is slow, 5s should be enough
    Start-Sleep -Seconds 5
    $allGames = $ChromeDriver.FindElementsByCssSelector("div.result-title.gameName") 

And inside that is a whose Text I want to retrieve. Neither names of the nor is unique. There's hundreds of divs and spans with the same name. So I can't access them directly.

I only want the text from the span, if its div has the text "abc"

The rudimentary knowledge I have with powershell tells me to do this

foreach ($game in $allGames) {
    $game.GetType() #=RemoteWebElement
    if ($game.Text -eq "abc") {
        Write-Host "Found something!"
        $span = $game.FindElementsByCssSelector("span.search-listing-count-text")
        $span.Text
    }

}

However $span contains nothing

I don't understand if I'm failing at understanding Selenium (which I don't even know what it is. Google told me I could use it to find stuffs on sites) or if I'm failing to understand the object oriented aspects of powershell (which I don't :))

What am I missing?

The html snippet:

<div class="search-results">
    <div class="result-title gameName">abc
        </div>
    <div class="result-info">
        <span class="search-listing-count-text">123
            </span>
        </div>
</div>
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352

2 Answers2

0

Your problem: You find the div with abc Than you need to go BACK 1 level to the: And then you want to find your div. The div you search is NOT a Child of the abc div

CssSelector and going back is not an option, so I used Xpath (Google Xpath for more info). Maybe you need to use "/..//" (remove the first .)

$span = $game.FindElementByXPath("./..//span[@class='search-listing-count-text']")

Note: Running selenium from powershell, thats new for me, leerling everyday. Nice!

Taco Verhagen
  • 222
  • 1
  • 6
  • " The div you search is NOT a Child of the abc div" Haha yeah I never realised. Thanks for the hint, helped me out with another issue as mentioned in above comment! I've moved on to python for new personal project. Figured knowing some basics in there could be useful. Though I find it hard to get hints from vscode when I don't specify the types inside my functions, but I don't understand classes and stuff so it's difficult. I digress. Thanks again! – user2076553 Feb 05 '22 at 09:13
0

Rebuilding the HTML you will get:

<div class="search-results">
    <div class="result-title gameName">abc</div>
    <div class="result-info">
        <span class="search-listing-count-text">123</span>
    </div>
</div>

Now, allGames would contain the _DIV_s with classnames result-title and gameName

$allGames = $ChromeDriver.FindElementsByCssSelector("div.result-title.gameName")

The required SPAN is the descendent of the DIV which is a sibling to the collected node within the list $allGames.


Solution

To select the required SPANs with respect to the nodes in the list $allGames you can use the following Locator Strategy:

  • XPath:

    foreach ($game in $allGames) {
        $game.GetType() #=RemoteWebElement
        if ($game.Text -eq "abc") {
            Write-Host "Found something!"
            $span = $game.FindElementByXPath("//ancestor::div[1]//div[@class='result-info']/span")
            $span.Text
        }
    }
    
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • 1
    When I woke up the next day I just tried $span = $game.FindElementByXPath("./following::span") And it worked! Now I wanted to do something similar in new mini-project. But the ./following always took me outside of my div. And I couldn't for the life of me figure out why, since I have another script doing the exact same thing. Remembered this post, and I never saw that my gameName div here is being closed before my span! The realisation helped me solve new problem as well. Thanks alot! – user2076553 Feb 05 '22 at 08:46