Powershell - Webseite auslesen und Abspeichern ein paar Probleme
Hallo alle miteinander,
ich hab die Aufgabe eine Webseite auszulesen um Einsatzdaten der Feuerwehr daraus zu gewinnen. Das habe ich soweit auch schon am laufen. Dazu ist es notwendig mit Cookies zu arbeiten. So schaut das aus.
das kommt dabei so raus
Soweit so gut jetzt habe ich noch 2 Problem
1. Lat und bei Lng muss ist anstelle des , einen . setzten da die verarbeitende Software das nur so versteht. Das habe ich so versucht
das funktioniert auch aber nicht ganz so wie ich das möchte. So wir eine neue Zeile gemacht und nicht die vorhanden geändert.
Bei dem Punkt EinsatzErzeugt müsste das Datum und die Uhrzeit so angezeigt werden 01.01.2019 23:00:00
Wie ich das so bekomme habe ich geschafft aber wie ich es ersetze leider auch wieder nicht.
2. Dieser Script sollt immer laufen und die Webseite überprüfen ob eine Veränderung stattgefunden hat. Zu dem Punkt habe ich noch nicht wirklich etwas gefunden. Wenn kein Einsatz ist und ich den Script ausführe wir eine 0 Bit Größe Datei gemacht da die Webseite dann keinen Inhalt hat. Toll wäre es wenn das so ist das keine Datei angelegt wird und dann nach 30 sek erneut angefragt wird ob jetzt eine Änderung ist.
Ich hoffe ich konnte mein Anliegen verdeutlichen und bin über jede Hilfe sehr dankbar. Sollte jemand eine andere Lösung für die Aufgabe haben dann bitte her damit
LG Alex
ich hab die Aufgabe eine Webseite auszulesen um Einsatzdaten der Feuerwehr daraus zu gewinnen. Das habe ich soweit auch schon am laufen. Dazu ist es notwendig mit Cookies zu arbeiten. So schaut das aus.
[System.Uri]$uri="https://demo.demo/"
$Cookie= New-Object System.Net.Cookie
$Cookie.Name = "demo"
$Cookie.Value = "demo"
$Cookie.Domain = $uri.DnsSafeHost
$WebSession = New-Object Microsoft.PowerShell.Commands.WebRequestSession
$WebSession.Cookies.Add($Cookie)
$props= @{ Uri=$uri.AbsoluteUri
WebSession=$Websession}
$data = Invoke-RestMethod @props
$data.Einsatzdata | Format-List -Property EinsatzID,Alarmstufe,Meldebild,Lat,Lng,Nummer1,Plz,Strasse,Ort,Bemerkung,EinsatzErzeugt,Melder,MelderTelefon > "c:\temp\einsatz.txt"
das kommt dabei so raus
EinsatzID : XXX
Alarmstufe : B2
Meldebild : Wohnungsbrand
Lat : 99,999999
Lng : 99,999999
Nummer1 : 99
Plz : 9999
Strasse : XXX
Ort : XXX
Bemerkung : XXX
EinsatzErzeugt : 2019-08-21T11:36:56.6284335+02:00
Melder : Max Mustermann
MelderTelefon : 000
Soweit so gut jetzt habe ich noch 2 Problem
1. Lat und bei Lng muss ist anstelle des , einen . setzten da die verarbeitende Software das nur so versteht. Das habe ich so versucht
$data.Einsatzdata.Lat -Replace ',', '.'
Bei dem Punkt EinsatzErzeugt müsste das Datum und die Uhrzeit so angezeigt werden 01.01.2019 23:00:00
$zeit = Get-Date -Format "dd/MM/yyyy HH:mm:ss"
2. Dieser Script sollt immer laufen und die Webseite überprüfen ob eine Veränderung stattgefunden hat. Zu dem Punkt habe ich noch nicht wirklich etwas gefunden. Wenn kein Einsatz ist und ich den Script ausführe wir eine 0 Bit Größe Datei gemacht da die Webseite dann keinen Inhalt hat. Toll wäre es wenn das so ist das keine Datei angelegt wird und dann nach 30 sek erneut angefragt wird ob jetzt eine Änderung ist.
Ich hoffe ich konnte mein Anliegen verdeutlichen und bin über jede Hilfe sehr dankbar. Sollte jemand eine andere Lösung für die Aufgabe haben dann bitte her damit
LG Alex
Please also mark the comments that contributed to the solution of the article
Content-Key: 487541
Url: https://administrator.de/contentid/487541
Printed on: April 19, 2024 at 09:04 o'clock
18 Comments
Latest comment
Daten im Format-List Format zu bearbeiten macht man nicht, das ist Humbug! Also direkt die Objekte bearbeiten.
Was die an Inhalt hat können wir hier ja nicht testen mangels URL. Lass dir mit Get-Member die zurückgegebenen Werte anzeigen dann kannst du entsprechend mit if Abfrage verzweigen.
$result = $data.Einsatzdata | select EinsatzID,Alarmstufe,Meldebild,Lat,Lng,Nummer1,Plz,Strasse,Ort,Bemerkung,EinsatzErzeugt,Melder,MelderTelefon
$result.Lat = $result.Lat.toString().replace(',','.')
$result.Lng = $result.Lng.toString().replace(',','.')
$result.EinsatzErzeugt = Get-Date $result.EinsatzErzeugt.toString() -F "dd/MM/yyyy HH:mm:ss"
# export als CSV
$result | export-csv "c:\temp\einsatz.csv" -NoType -Delimiter ";" -Encoding UTF8
# oder als Text
$result | fl * | sc "c:\temp\einsatz.txt"
Dieser Script sollt immer laufen und die Webseite überprüfen ob eine Veränderung stattgefunden hat
Aufgabenplanung.Wenn kein Einsatz ist und ich den Script ausführe wir eine 0 Bit Größe Datei gemacht da die Webseite dann keinen Inhalt hat.
Prüfe halt einfach die Variable in Zeile 13 des Invoke-Restmethod auf Inhalt mit nem simplen if(){ } ...Was die an Inhalt hat können wir hier ja nicht testen mangels URL. Lass dir mit Get-Member die zurückgegebenen Werte anzeigen dann kannst du entsprechend mit if Abfrage verzweigen.
Oben korrigiert, habe hier ja die deine Originaldaten nicht sorry! Wenn du die URL posten würdest könnte man es direkt fertig machen.
z.B.
Aber ich weiß ja nicht welchen Inhalt dein $data hat wenn die Webseite nichts liefert deswegen kann ich hier nur mutmaßen. Deswegen der Hinweis lass dir den Inhalt bzw. die Member von $data ausgeben
Wenn dann die Fehlermeldung kommt das es keine Member von einem null Objekt gibt dann funktioniert obige Abfrage, ansonsten ist die Bedingung anzupassen, je nachdem was Invoke-RestMethod liefert wenn die Webseite keinen Inhalt zurückgibt.
Aufgabenplanung das er alle 30 sek den Script laufen lassen soll? Ok dachte vielleicht gibt es da direkt etwas.
Kannst auch eine while(){} DauerSchleife laufen lassen. Jacke wie Hose.Ok if(){ } ... leider bin ich nicht sehr vertraut mit PowerShell und kann jetzt nicht ganz verstehen wie das helfen soll kann.
Naja, nachschlagen wäre mal die erste Methode ... https://www.windowspro.de/script/if-else-switch-bedingte-anweisungen-pow ...z.B.
if ($data){
$result = $data.Einsatzdata | select EinsatzID,Alarmstufe,Meldebild,Lat,Lng,Nummer1,Plz,Strasse,Ort,Bemerkung,EinsatzErzeugt,Melder,MelderTelefon
$result.Lat = $result.Lat.toString().replace(',','.')
$result.Lng = $result.Lng.toString().replace(',','.')
$result.EinsatzErzeugt = Get-Date $result.EinsatzErzeugt.toString() -F "dd/MM/yyyy HH:mm:ss"
# export als CSV
$result | export-csv "c:\temp\einsatz.csv" -NoType -Delimiter ";" -Encoding UTF8
# oder als Text
$result | fl * | out-string | sc "c:\temp\einsatz.txt"
}
$data | Get-Member
Was gibt ein
zurück? Es gibt hier nämlich einige Varianten wie Daten zurückgegeben werden können, Der JSON String wird normalerweise von Invoke-Restmethod direkt zu einem Object oder einem Array konvertiert und je nachdem wie das JSON formatiert ist ist dies eben unterschiedlich aufgebaut und muss unterschiedlich behandelt werden! Wenn das nämlich ein Array ist muss das Ansprechen z.B. so geschehen $data.EinsatzID
$data.GetType()
Ok in dem Fall sollte ein zwischengeschaltetes Out-string helfen
$result | fl * | out-string | sc "c:\temp\einsatz.txt"
Kannst ja noch ein Detail vorher noch auf Unterschied zum letzten Request checken und nur dann in die Datei ausgeben (ergänzt).
# rest ... von vor Zeile 13
$lastID = 0
while($true){
$data = Invoke-RestMethod @props
if ($data){
$result = $data.Einsatzdata | select EinsatzID,Alarmstufe,Meldebild,Lat,Lng,Nummer1,Plz,Strasse,Ort,Bemerkung,EinsatzErzeugt,Melder,MelderTelefon
if ($result.EinsatzID -ne $lastID){
$result.Lat = $result.Lat.toString().replace(',','.')
$result.Lng = $result.Lng.toString().replace(',','.')
$result.EinsatzErzeugt = Get-Date $result.EinsatzErzeugt.toString() -F "dd/MM/yyyy HH:mm:ss"
$result | fl * | out-file "c:\temp\einsatz.txt"
$lastID = $result.EinsatzID
}
}
sleep -Seconds 5
}
Wenn ich zB schauen will ob sich EinsatzID geändert hat und wenn die nicht vorhanden ist schreibe auch keine Datei.
Ist oben eingesetzt. Das ganze speichert die letzte EinsatzID beim schreiben der Textdatei in der Variablen $lastID. Wenn bei einem erneuten Abruf der Seite sich die aktuelle EinsatzID von der letzten unterscheidet dann wird die Textdatei neu geschrieben ansonsten nicht. Wäre ja Blödsinn alle 5 Sekunden die Datei neu zu schreiben obwohl sich nichts auf der Seite geändert hat .Ich gehen hier natürlich davon aus das die EinsatzID bei jedem neuen Einsatz anders ist als der vorherige. Ansonsten ändere die Eigenschaft einfach auf die die du dazu benutzen willst.
Das ist einfach nur das initiales Deklarieren der Variablen ohne Inhalt, hinterher enthält die ja jeweils immer die letzte ID.
Auch hier hilft wieder nachschlagen: Variablen in PowerShell: Namen, Werte, Datentypen
Auch hier hilft wieder nachschlagen: Variablen in PowerShell: Namen, Werte, Datentypen
Da hilft nur üben üben und nochmal üben, wie überall . Selbst Übungsaufgaben stellen und so lange dran bleiben bis es klappt auch mal ohne Forum, nur so bleibt es wirklich hängen.
Viel Erfolg weiterhin.
Ciao.
Viel Erfolg weiterhin.
Ciao.
In dem Fall ist die EinsatzID vom Typ Integer bzw. eine Zahl, da reicht es wenn du in die Deklaration von $lastID statt einem String eine 0 schreibst, dann geht es ebenfalls problemlos mit -ne, aber wenn die ID sowieso immer größer wird geht das natürlich auch mit -gt .
Aber auch wenn der Inhalt von $lastID ein String wäre wäre der Vergleich einer Zahl mit einem leerem String $true muss also auch gehen, kannst du ganz einfach selbst testen
Ergibt
If Bedingung wird also ausgeführt.
In dem Fall musst du die Zeile
Dann ist das damit schon abgefackelt. Ich war davon ausgegangen das die Webseite überhaupt nichts zurückgibt ...
Aber auch wenn der Inhalt von $lastID ein String wäre wäre der Vergleich einer Zahl mit einem leerem String $true muss also auch gehen, kannst du ganz einfach selbst testen
10 -ne ""
$true
mit -gt anstelle von -ne wird nur eine Datei erstellt wenn auch etwas drin steht.
Achso so die Website gibt also in jedem Fall immer ein Object zurück, nur eben alle Properties ohne Werte? In dem Fall ist die eine IF-Bedingung die $data checkt nicht passend.In dem Fall musst du die Zeile
if ($data){
so schreibenif ($data.EinsatzData.EinsatzID -gt 0){