Hallo zusammen,
ich verwende Powershell und Selenium um Webelemente auf einer Webseite anzusteuern. Bei mehreren Dropdown-Menüs wird eine Auswahl getroffen und dann wird ein Button geklickt um Daten zu erhalten. Funktioniert soweit auch ganz gut, allerdings macht eines der Dropdown-Menüs regelmäßig Zicken und springt nach der Auswahl einfach zurück auf den Ursprungswert und mein Code rennt weiter.
Also war mein Gedanke den Wert des Dropdown-Menüs zu prüfen bevor ich den Code weiter laufen lasse, mit Hilfe einer Do-Until Schleife.
Nun hat sich dabei aber herausgestellt, dass das verflixte Dropdown-Menü zu allen Zeiten immer die gleiche Text-Eigenschaft besitzt, selbst dann wenn eigentlich ein ganz anderer Wert darin angezeigt wird.
Beispiel: Im Dropdown-Menü steht per default "2024 Juli". Wenn ich jedoch mit "Write-Host $Element.Text" die Text-Eigenschaft abfrage dann bekomme ich als Rückgabewert "All".
Das Blöde ist, "All" ist genau der Wert, den ich auswählen möchte und die Bedingung, dass mein Code weiterläuft. Also erst wenn "All" wirklich ausgewählt wurde, soll mein Code weiterlaufen.
Hier der ganze Code, inklusive dem Laden der Triber für diverse Browser:
# Browsertreiber laden
function Create-Browser {
param(
[Parameter(mandatory=$true)][ValidateSet('Chrome','Edge','Firefox')][string]$browser,
[Parameter(mandatory=$false)][bool]$HideCommandPrompt = $true,
[Parameter(mandatory=$false)][string]$driverversion = '',
[Parameter(mandatory=$false)][object]$options = $null
)
$driver = $null
function Load-NugetAssembly {
[CmdletBinding()]
param(
[string]$url,
[string]$name,
[string]$zipinternalpath,
[switch]$downloadonly
)
if($psscriptroot -ne ''){
$localpath = join-path $psscriptroot $name
}else{
$localpath = join-path $env:TEMP $name
}
$tmp = "$env:TEMP\$([IO.Path]::GetRandomFileName())"
$zip = $null
try{
if(!(Test-Path $localpath)){
Add-Type -A System.IO.Compression.FileSystem
write-host "Downloading and extracting required library '$name' ... " -F Green -NoNewline
(New-Object System.Net.WebClient).DownloadFile($url, $tmp)
$zip = [System.IO.Compression.ZipFile]::OpenRead($tmp)
$zip.Entries | ?{$_.Fullname -eq $zipinternalpath} | %{
[System.IO.Compression.ZipFileExtensions]::ExtractToFile($_,$localpath)
}
write-host "OK" -F Green
}
if (Get-Item $localpath -Stream zone.identifier -ea SilentlyContinue){
Unblock-File -Path $localpath
}
if(!$downloadonly.IsPresent){
Add-Type -Path $localpath -EA Stop
}
}catch{
throw "Error: $($_.Exception.Message)"
}finally{
if ($zip){$zip.Dispose()}
if(Test-Path $tmp){del $tmp -Force -EA 0}
}
}
# Load Selenium Webdriver .NET Assembly and dependencies
Load-NugetAssembly 'https://www.nuget.org/api/v2/package/Newtonsoft.Json' -name 'Newtonsoft.Json.dll' -zipinternalpath 'lib/net45/Newtonsoft.Json.dll' -EA Stop
Load-NugetAssembly 'https://www.nuget.org/api/v2/package/Selenium.WebDriver' -name 'WebDriver.dll' -zipinternalpath 'lib/netstandard2.0/WebDriver.dll' -EA Stop
if($psscriptroot -ne ''){
$driverpath = $psscriptroot
}else{
$driverpath = $env:TEMP
}
switch($browser){
'Chrome' {
$chrome = Get-Package -Name 'Google Chrome' -EA SilentlyContinue | select -F 1
if (!$chrome){
throw "Google Chrome Browser not installed."
return
}
Load-NugetAssembly "https://www.nuget.org/api/v2/package/Selenium.WebDriver.ChromeDriver/$driverversion" -name 'chromedriver.exe' -zipinternalpath 'driver/win32/chromedriver.exe' -downloadonly -EA Stop
# create driver service
$dService = [OpenQA.Selenium.Chrome.ChromeDriverService]::CreateDefaultService($driverpath)
# hide command prompt window
$dService.HideCommandPromptWindow = $HideCommandPrompt
# create driver object
if ($options){
$driver = New-Object OpenQA.Selenium.Chrome.ChromeDriver $dService,$options
}else{
$driver = New-Object OpenQA.Selenium.Chrome.ChromeDriver $dService
}
}
'Edge' {
$edge = Get-Package -Name 'Microsoft Edge' -EA SilentlyContinue | select -F 1
if (!$edge){
throw "Microsoft Edge Browser not installed."
return
}
Load-NugetAssembly "https://www.nuget.org/api/v2/package/Selenium.WebDriver.MSEdgeDriver/$driverversion" -name 'msedgedriver.exe' -zipinternalpath 'driver/win64/msedgedriver.exe' -downloadonly -EA Stop
# create driver service
$dService = [OpenQA.Selenium.Edge.EdgeDriverService]::CreateDefaultService($driverpath)
# hide command prompt window
$dService.HideCommandPromptWindow = $HideCommandPrompt
# create driver object
if ($options){
$driver = New-Object OpenQA.Selenium.Edge.EdgeDriver $dService,$options
}else{
$driver = New-Object OpenQA.Selenium.Edge.EdgeDriver $dService
}
}
'Firefox' {
$ff = Get-Package -Name "Mozilla Firefox*" -EA SilentlyContinue | select -F 1
if (!$ff){
throw "Mozilla Firefox Browser not installed."
return
}
Load-NugetAssembly "https://www.nuget.org/api/v2/package/Selenium.WebDriver.GeckoDriver/$driverversion" -name 'geckodriver.exe' -zipinternalpath 'driver/win64/geckodriver.exe' -downloadonly -EA Stop
# create driver service
$dService = [OpenQA.Selenium.Firefox.FirefoxDriverService]::CreateDefaultService($driverpath)
# hide command prompt window
$dService.HideCommandPromptWindow = $HideCommandPrompt
# create driver object
if($options){
$driver = New-Object OpenQA.Selenium.Firefox.FirefoxDriver $dService, $options
}else{
$driver = New-Object OpenQA.Selenium.Firefox.FirefoxDriver $dService
}
}
}
return $driver
}
$url = 'https://www.cboe.com/delayed_quotes/nsc/quote_table'
Write-Host 'Url: ' $url
# $browser = Create-Browser -browser Chrome
$browser = Create-Browser -browser Edge
$browser.Url = $url
$navi = $browser.Navigate()
Start-Sleep -Seconds 1
$browser.Manage().Window.FullScreen()
#Cookie-Meldung ausblenden (Agree Button)
$agreeButton = $browser.FindElement([OpenQA.Selenium.By]::XPath("//button[contains(@class, 'button--solid') and contains(@class, 'privacy-alert__agree-button') and text()='I agree']"))
$agreeButton.Click()
#Optionsrange (Drowpdown-Menü) auf "All" stellen
$optionsrange = $browser.FindElement([OpenQA.Selenium.By]::XPath("//input[contains(@class, 'ReactSelect__input') and contains(@id, 'select_5')]"))
$actions = [OpenQA.Selenium.Interactions.Actions]::new($browser)
$actions.SendKeys($optionsrange,'All')
$actions.SendKeys($optionsrange,[OpenQA.Selenium.Keys]::Enter)
$actions.Build()
$actions.Perform()
Start-Sleep -Seconds 3
#Expirations (Drowpdown-Menü) auf "All" stellen
$expirations = $browser.FindElement([OpenQA.Selenium.By]::XPath("//input[contains(@class, 'ReactSelect__input') and contains(@id, 'select_7')]"))
$singlevalue = $browser.FindElement([OpenQA.Selenium.By]::XPath("//div[contains(@class, 'ReactSelect__single-value') and contains(@class, 'css-1dimb5e-singleValue')]"))
write-host $singlevalue.Text
do {
$actions = [OpenQA.Selenium.Interactions.Actions]::new($browser)
$actions.SendKeys($expirations,'All')
$actions.SendKeys($expirations,[OpenQA.Selenium.Keys]::Enter)
$actions.Build()
$actions.Perform()
Start-Sleep -Seconds 1
write-host $singlevalue.Text
} until ($singlevalue.Text -eq 'All')
# Warten bis der Browser die Daten (im Hintergrund) geladen hat
Start-Sleep -Seconds 2
# Dann erst die Optionskette anzeigen
$viewchainbutton = $browser.FindElement([OpenQA.Selenium.By]::XPath("//button[contains(@class, 'Button__StyledButton-cui__sc-1ahwe65-2') and contains(@class, 'hMfKkd')]"))
Start-Sleep -Seconds 1
$viewchainbutton.Click()
# Link-Button klicken
$browser.FindElement([OpenQA.Selenium.By]::XPath("//a[contains(@type, 'button') and contains(@download, 'quotedata.csv')]")).click()
Start-Sleep -Seconds 2
Write-Output "Ready"
$browser.Quit()
Hier nochmal explizit die Codezeilen um die es geht:
$singlevalue = $browser.FindElement([OpenQA.Selenium.By]::XPath("//div[contains(@class, 'ReactSelect__single-value') and contains(@class, 'css-1dimb5e-singleValue')]"))
write-host $singlevalue.Text
do {
$actions = [OpenQA.Selenium.Interactions.Actions]::new($browser)
$actions.SendKeys($expirations,'All')
$actions.SendKeys($expirations,[OpenQA.Selenium.Keys]::Enter)
$actions.Build()
$actions.Perform()
Start-Sleep -Seconds 1
write-host $singlevalue.Text
} until ($singlevalue.Text -eq 'All')
Hat jemand eine Ahnung, wie man das Dropdown-Menü so abfragt, dass man tatsächlich den darin ausgewählten Wert erhält?
Es würde mir auch helfen wenn mir jemand sagen kann weshalb dieses Dropdown-Menü in vielen Fällen einfach wieder auf den default Wert zurückspringt.
Beste Grüße
Marc