Werte aus einer Webseite auslesen

  • VB.NET

Es gibt 23 Antworten in diesem Thema. Der letzte Beitrag () ist von SpaceyX.

    Werte aus einer Webseite auslesen

    Hi Leute,
    da bin ich wieder mit einem Problem:
    mein Informatiklehrer hat mich gefragt, ob ich ihm mit vb.net helfen kann und ich hab ja gesagt.
    Sein Problem ist: Ich soll ein Tool schreiben, welches von der webseite "www.wetter.de" die Wetterdaten für den Standort unserer Schule ausliest und in eine .INI-Datei schreibt.
    Das schreiben von INIs ist mir bekannt, da ich mich jedoch im bereich HTML und auslesen von Werten aus einer HTML-Seite überhaut nicht auskenne, frage ich euch (mal wieder) um hilfe... :D
    Ich weiss, es gibt sehr viele topics darüber, aber mit HTML bin ich leider noch ein Anfänger

    Kann mir da irgendjemand in irgendeiner weise helfen.
    Ich werde vermutlich auch beispielcodes brauchen, wenn ich das nicht raffe ;)

    Falls ihr die Adresse meiner Schule als Test braucht: Leibniz-Gymnasium-Östringen, 76684 Östringen, Baden, Deutschland

    Vielen Dank,
    wincrash


    P.S.: Ich weiss, ich hätte nicht unbedingt einen neuen Post öffnen sollen, aber ich habs in allen anderen Themen nicht gerafft... :(
    (\_/) Das ist Hase.
    (O.o) Kopiere Hase in deine Signatur
    (> <) und hilf ihm so auf seinem Weg zur Weltherrschaft.
    o/

    geh auf wetter.de und finde die genaue URL für Deinen ort raus.

    dann mach folgendes

    VB.NET-Quellcode

    1. Imports System.Net
    2. Imports System.IO
    3. Public Class Form1
    4. Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    5. Dim hReq As HttpWebRequest = DirectCast(HttpWebRequest.Create("http://www.wetter.de/wettervorhersage/49-7772-22/wetter-germering.html"), HttpWebRequest)
    6. Dim hRes As HttpWebResponse = DirectCast(hReq.GetResponse(), HttpWebResponse)
    7. Dim s As Stream = hRes.GetResponseStream()
    8. Dim sR As New StreamReader(s)
    9. Dim webPage As String = sR.ReadToEnd()
    10. sR.Close()
    11. s.Close()
    12. sR = Nothing
    13. s = Nothing
    14. hReq = Nothing
    15. hRes = Nothing
    16. MessageBox.Show(webPage)
    17. End Sub
    18. End Class


    dies gibt dir den HTML-code der entsprechenden seite auf wetter.de aus. in der variablen webPage ist der HTML-code enthalten. alles, was nun noch zu tun ist, ist nach den gewünschten werten suchen. benutz hier regualExpressions oder sonst was...
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    Vielen Dank fpür die schnelle Antwort,
    ich werde das gleich mal ausprobieren

    ich halte dich auf dem lafendemn,
    wincrash


    edit:
    OK, der Code war sehr hilfreich, mein problem ist nur noch, dass ich aus dem code die Werte, wie zum beispiel "Luftfeuchtigkeit" oder "Maximale Temperatur" etc. nicht auslesen kann - genauer gesagt ich finde sie in dem ganzen code nicht. kann mir da jemand helfen?

    im anhang ist der html-code ...
    Dateien
    (\_/) Das ist Hase.
    (O.o) Kopiere Hase in deine Signatur
    (> <) und hilf ihm so auf seinem Weg zur Weltherrschaft.

    Dieser Beitrag wurde bereits 6 mal editiert, zuletzt von „Wincrash“ ()

    huhu,

    doch die werte stehen schon in dem quelltext. such mal nach "Luftfeuchtigkeit". ist ziemlicher brainfuck, die werte aus diesem quelltext auszulesen. probier mal, gehen tuts...
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    jaah, schon ne gute idee :D
    brainfuck trifft's !! :D


    Ich hab die stelle gefunden, hab aber noch das problem:
    du kennst ja "IndexOf"-Methode - gibts da nicht auch sowas wie "SecondIndexOf" oder "ThirdIndexOf"?
    ich hab da nämlich im code ne zeile die sich mehrmahls wiederholt, und beim 2. indexOf wäre dann die wichtige information - es ist aber nicht der LastIndex - schön wärs ;)

    wincrash

    edit: ok hat sich erledigt. weiss trozdem jemand,wie man easy variablen einen wert zuordnen kann, der sich hier befindet:
    BEISPIELCODE:

    HTML-Quellcode

    1. <div class="forecastInfo rain"> <div class="headline_h4">Niederschlag</div>
    2. <dl>
    3. <dt>Menge</dt><dd>2 - 4&nbsp;l/m&sup2;</dd>
    4. <dt>Risiko</dt><dd>88&nbsp;%</dd>
    5. <dt>Luftfeuchtigkeit</dt><dd>78&nbsp;%</dd>
    6. </dl>
    7. </div>


    und ich will den wert hinter risiko in eine variable einlesen (in dem fall 88 % bzw. ""<dd>88&nbsp;%</dd> "")

    WIE mach ich das?

    ich weis der index vom wort ""Risiko"" ist irgendwo bwi 3560 in dem code, aber wenn sich mal die position ändert, wirds blöd...


    kann da jemand helfen?
    wincrash
    (\_/) Das ist Hase.
    (O.o) Kopiere Hase in deine Signatur
    (> <) und hilf ihm so auf seinem Weg zur Weltherrschaft.

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Wincrash“ ()

    hey,

    ich hab mal was gesucht, hat ein bisschen gedauert, da ich zwischenzeitlich zur arbeit musste...

    hast mal überlegt, was passiert, wenn wetter.de das layout der seite ändert? dann funktioniert wahrscheinlich das auslesen der seite nicht mehr und Du stehst wieder vor dem selben problem. ich hab mal geguggt, ob wetter.de vielleicht einen webservice anbietet, der die daten als xml oder sonst was bereitstellt. gibt es leider nicht :( weitere recherchen haben ergeben, dass google eine wetter api anbietet, die ist leider abgeschalten worden. dann kam ich auf yahoo. yahoo bietet noch eine wetter-api, die Dir die daten als xml anbietet. schaus Dir mal an:

    developer.yahoo.com/weather/

    hier ist die gesamte api beschrieben, eigentlich sehr sehr einfach.

    um an den code für Deine stadt zu kommen, besuch diese seite und gibt den namen Deiner stadt an:

    weather.yahoo.com/

    in der url-zeile im browser kannst Du diesen code dann ablesen.

    ich würd auf die yahoo-wetter-api umschwenken. so ersparst Du Dir nen haufen brainfuck. musst halt entscheiden, ob Dir die daten genügen, die Du von dort bekommst. webseiten auslesen hat halt immer das risiko, dass sie ihr layout ändern und die ganze arbeit fürn ar.... war...

    o/
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    So leicht würde ich mich da nicht geschlagen geben.

    Ich spinne jetzt einfach mal die Überlegungen von SpaceyX ein bischen weiter...

    Folgendes haben wir ja schon:

    VB.NET-Quellcode

    1. Imports System.Net
    2. Imports System.IO
    3. Public Class Form1
    4. Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    5. Dim hReq As HttpWebRequest = DirectCast(HttpWebRequest.Create("http://www.wetter.de/wettervorhersage/49-7772-22/wetter-germering.html"), HttpWebRequest)
    6. Dim hRes As HttpWebResponse = DirectCast(hReq.GetResponse(), HttpWebResponse)
    7. Dim s As Stream = hRes.GetResponseStream()
    8. Dim sR As New StreamReader(s)
    9. Dim webPage As String = sR.ReadToEnd()
    10. sR.Close()
    11. s.Close()
    12. sR = Nothing
    13. s = Nothing
    14. hReq = Nothing
    15. hRes = Nothing
    16. MessageBox.Show(webPage)
    17. End Sub
    18. End Class


    WIe schon gesagt haben wir jetzt den gesammten Inhalt der Webiste in einer String Variable. Das ist alles ein wenig zu viel auf einmal. Desswegen grenzen wir das ganze jetzt einfach mal ein bischen ein:

    VB.NET-Quellcode

    1. Dim Startpos As Integer = webpage.IndexOf("Luftfeuchtigkeit") 'Startposition im Seitenquelltext ermitteln
    2. Dim Zwischenstring As String = webpage.Substring(Startpos, 40) 'Einen String von 40 Zeichen herausschneiden
    3. Dim i As Integer = 0
    4. Dim Luftfeuchtigkeit As Integer
    5. Do Until i = 39
    6. If IsNumeric(Zwischenstring(i)) = True Then
    7. If IsNumeric(Zwischenstring(i + 2)) = True Then
    8. Luftfeuchtigkeit = Convert.ToInt32(Zwischenstring(i) & Zwischenstring(i + 1) & Zwischenstring(i + 2))
    9. Exit Do
    10. Else
    11. Luftfeuchtigkeit = Convert.ToInt32(Zwischenstring(i) & Zwischenstring(i + 1))
    12. Exit Do
    13. End If
    14. End If
    15. i = i + 1
    16. Loop
    17. MessageBox.Show("Luftfeuchtigkeit: " & Luftfeuchtigkeit & " %")


    Der Code dürfte für dich recht selbsterklärend sein. Zuerst suche ich den Quelltext nach dem Wort Luftfeuschtigkeit ab und ermittle die Startposition im Quelltext. Damit kann ich dann einen 40 Zeichenstring "Herausschneiden" um die Suchparameter einzugrenzen. Den kleinen String kann ich dann Zeichen für Zeichen durchgehen bis ich auf einen Integer Stoße^^

    Die Jungs von Wetter.de müssten bei dem Code ihre Seite schon sehr massiv verändern damit das Script nicht mehr greift^^
    o/

    was ich Dir noch an hilfe anbieten kann ist folgender rat:

    es gibt z. b. für google chrome ne funktion "element untersuchen". zu erreichen über das kontextmenü des browsers. für firefox oder opera gibts bestimmt ähnliches. opera stellt Dir die seite auch in 3d dar. unglaubich, was sich manche menschen ausdenken :) nur so nebenbei. gerade für solche vorhaben sind diese "html-inspectoren" unglaublich nützlich, da sie aus dem müll, was in der textdatei steht, strukturierten und gut leserlichen html-quelltext machen. so findest Du sehr schnell, wonach Du suchen musst. ich spreche jetzt für chrome. hast Du diese funktion gewählt, hast Du unten ne lupe, diese wählst Du aus und bewegst den cursor über die elemente, die Dich interessieren, wählst sie mit nem klick aus und der zugehörige html-code wird Dir angezeigt.

    was dann in .net gehen sollte ist folgendes. es gibt ne klasse html-document. versuch mal, den quelltext in ein solches objekt zu laden. hier solltest Du dann die möglichkeit haben, mit .GetElementByName oder .GetElementByID direkt auf die informationen zuzugreifen. dies unter vorbehalt. ich werds, wenn ich zuhause bin, selber ausprobieren.
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    was dann in .net gehen sollte ist folgendes. es gibt ne klasse html-document. versuch mal, den quelltext in ein solches objekt zu laden. hier solltest Du dann die möglichkeit haben, mit .GetElementByName oder .GetElementByID direkt auf die informationen zuzugreifen. dies unter vorbehalt. ich werds, wenn ich zuhause bin, selber ausprobieren.


    Ich lasse mich gern korrigieren, aber soweit ich weis geht das nur bei Formularen und dient in erster Linie dazu Webformulare ausfüllen zu können.

    Da in dem Fall aber kein HTML Formular vorhanden ist, sondern lediglich eine Ausgabe von Informationen Stattfindet, gibt es hier auch keine Elemente die du dann ansprechen könntest.

    In dem Fall kannst du nur wie ein oder andere Methode entwerfen um den Seiteninhalt deinen Bedürfnissen entsprechend zu filtern.

    Ich benutze für das durchsuchen von Webistes gerne mal Opere Dragonfly. Damit kann man recht schnell und auch einfach finden was man sucht^^
    moin o/

    muss mich etwas korrigieren über das oben gesagte. erstens gibt nur die komponente "webbrowser" ein htmldocument zurück. das bedeutet, man muss den html-code erst in einen webbrowser laden und von dieser instanz bekommt man ein document. damit fällt das schon mal aus. ich hasse diese webbrowser-komponente. zweitens gibts in nem htmldocument die function "GetElementsByTagName", aber irgendwie gibt die nur schrott zurück. ich denke, die webbrowser-komponente und das dazugehörige htmldocument funktioniert nur richtig, wenn man es live lädt.

    also bleibt nur das auslesen des quellcodes. ich hab mir den in der s-bahn nochmal etwas genauer angeschaut. so viel brainfuck ists dann doch nicht, wenn man alle vbtabs und leerzeichen rauslöscht und das dann per "vblf" in einzelne zeilen splittet. ich leg mich erst mal schlafen, wenn Du dann noch keine lösung hast, dann schau ichs mir nochmal an.
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „SpaceyX“ ()

    hey hört sich alles klasse an,ich kanns jetzt noch nicht testen - ich geb euch etwa um 19:00 uhr bescheid
    wincrash

    scheiss schule... :(
    (\_/) Das ist Hase.
    (O.o) Kopiere Hase in deine Signatur
    (> <) und hilf ihm so auf seinem Weg zur Weltherrschaft.
    OK
    @ SpaceyX: wo befindet sich genau diese klasse - hab sie nicht gefunden aber deine idee hört sich klasse an.

    ich muss jetzt noch die anderen ansätze testen,
    wincrash
    (\_/) Das ist Hase.
    (O.o) Kopiere Hase in deine Signatur
    (> <) und hilf ihm so auf seinem Weg zur Weltherrschaft.
    o/

    bitte vergiss das, was ich über das htmldocument und webbrowser gesagt hab. ist keine schöne lösung.
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    Wenn du soetwas umsetzten willst wird dir nichts anderes über bleiben, als den kompletten Inhalt der Seite auszulesen und entsprechend zu prasen. Dabei helfen diverse Funktionen und Klassen.

    Ich hab jetzt meinen ersten bzw SpaceyX und meinen Code ( ich will ja nicht die ganzen Lohrbeeren alleine einheimsen) nochmal überarbeitet und das Wichtigste in eine Funktion gepackt

    VB.NET-Quellcode

    1. Imports System.IO
    2. Imports System.Net
    3. Public Class Form1
    4. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    5. Label1.Text = "Luftfeuschtigkeit " & Wertlesen("Luftfeuchtigkeit", TextBox1.Text) & " %"
    6. End Sub
    7. Public Function Wertlesen(ByVal Gesstring As String, ByVal URL As String) As Integer
    8. Dim hReq As HttpWebRequest
    9. Dim HRes As HttpWebResponse
    10. hReq = DirectCast(HttpWebRequest.Create(URL), HttpWebRequest)
    11. HRes = DirectCast(hReq.GetResponse(), HttpWebResponse)
    12. Dim s As Stream = HRes.GetResponseStream()
    13. Dim sR As New StreamReader(s)
    14. Dim webpage As String = sR.ReadToEnd
    15. sR.Close()
    16. s.Close()
    17. sR = Nothing
    18. s = Nothing
    19. hReq = Nothing
    20. HRes = Nothing
    21. Dim Startpos As Integer = webpage.IndexOf(Gesstring)
    22. Dim Zwischenstring As String = webpage.Substring(Startpos, 40)
    23. Dim i As Integer = 0
    24. Wertlesen = 0
    25. Do Until i = 39
    26. If IsNumeric(Zwischenstring(i)) = True Then
    27. If IsNumeric(Zwischenstring(i + 2)) = True Then
    28. Wertlesen = Convert.ToInt32(Zwischenstring(i) & Zwischenstring(i + 1) & Zwischenstring(i + 2))
    29. Exit Do
    30. Else
    31. Wertlesen = Convert.ToInt32(Zwischenstring(i) & Zwischenstring(i + 1))
    32. Exit Do
    33. End If
    34. End If
    35. i = i + 1
    36. Loop
    37. End Function
    38. End Class


    Die Funktion Wertlesen macht im endeffekt nichts anderes als der vorherige Code auch. Der einzige Vorteil an der Funktion ist, das du sie bequem öfter und für verschiedene Werte die du auslesen willst verwenden kannst. Allerdings muss ich dich warnen. Die Funktion ist jetzt spetziell auf deinen Wunsch zugeschnitten und kann daher wie du vielleicht dem Code entnehmen kannst nur Ganzzahlen von 01 bis 999 auslesen. Für alles andere müsste sie angepasst werden
    o/

    das ganze schreit irgendwie nach nem kleinen projekt. das gehört alles schön gekapselt. der code zum auslesen muss so allgemeingültig wie nur möglich sein. dann packt man den code in ne klasse "WeatherDataReader", die einem instanzen von "WeatherForecast" zurückgibt. das alles nur unter angabe der plz. dann erstellen wir daraus ne .dll und die verkaufen wir dann :) in nem weiteren schritt bauen wir ein schönes gui drum rum mit schönen bildern und nackten weibern und warten auf post von den wetter.de anwälten :)
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    o/ moin

    wir war heute nacht extremst langweilig. nach ein paar stunden arbeit kam die "Weather.dll" zum vorschein. im dateianhang findet ihr zwei .zip archive. eines mit einer demo-consolenanwendung, eines mit den code-dateien der dll. wenn sich jemand dazu berufen fühlt, kann er um das ganze ein hübsche wpf oder win-forms anwendung basteln, da hab ich leider nicht viel talent dazu. sicher kann man am source-code der .dll noch viel verbessern. vor allem an der routine, die die webseite ausliest. evtl. auch am klassendesign, aber ich bin ganz zufrieden damit. ein paar worte zur .dll, obwohl in der demo-anwendung eh alles steht.

    klasse "WeatherDataReader" -> konstruktor:

    VB.NET-Quellcode

    1. Public Sub New(ByVal url As Uri)
    2. Me.url = url
    3. End Sub


    dieser nimmt eine uri (uniform ressource identifyer) entgegen. um an die richtige url für eure stadt zu kommen, geht auf wetter.de, tippt im suchfeld eure stadt ein, trefft ggf. auf der folgenden seite eine genauere auswahl. danach sollte die seite mit der 8 tage übersicht kommen. diese url kopiert ihr euch und füttert den konstruktor damit. sollte ein ähnliches format haben, wie ich im demo benutze (germering).

    VB.NET-Quellcode

    1. Private WithEvents _wR As WeatherDataReader
    2. _wR = New WeatherDataReader(New Uri("http://www.wetter.de/wettervorhersage/49-7772-22/wetter-germering.html"))


    die klasse hat 3 events. eines gibt euch infos, sobald der html-code runtergeladen wurde, eines wenn er fertig geparst wurde und eines wird losgetreten, wenn ein fehler auftritt.

    die klassenfunktion:

    VB.NET-Quellcode

    1. Dim listForecasts As List(Of WeatherForecast) = Nothing
    2. listForecasts = _wR.GetWeatherForecast()


    gibt euch bei erfolg eine liste von "WeatherForecast" zurück. bevor ihr damit weiterarbeitet, prüft bitte ob sie "IsNothing" ist. tritt beim abfragen ein fehler auf, wird einerseits das event gefeuert, andererseits erhaltet ihr nothing als rückgabe. hier aufpassen!

    die klasse "WeatherForeCast" kapselt die ganzen daten. bei allen nummerischen daten hab ich als typ "Double" verwendet. da ich anfangs nicht sicher war, ob hier irgendwo nachkommastellen auftreten. war bei allen tests nicht der fall, somit hätts wohl auch ein "Integer" getan. eine ausnahme gibts bei der property "rainAmmount". hier werden oft z. b. 3-7 liter angegeben. dieser datentyp ist daher ein "String", falls sich jemand fragt. sunSet, sunRise sind vom typ "Date", sunshineHours ist vom typ "TimeSpan". die oder das property temperatures ist eine liste von "WeatherTemperatureInfo", da die angaben auf wetter.de in 4 tagesabschnitte unterteilt sind. in "WeatherTemperatureInfo" findet ihr den tagesabschnitt als "String", die gefühlte und die tatsächliche temperatur als "Double".

    ich glaub das wars im grossen und ganzen. ich hab total rote augen und muss erst mal ins bett. würd mich echt freuen, wenn wir gemeinsam eine kleine schöne anwendung um das ganze basteln, würd mich auch freuen, wenn jemand die .dll verbessert. ich hoffe, der TE lernt etwas draus und kopiert das ganze nicht nur. noch eines. der source-code ist für alle, er ist frei und darf kopiert und verteilt werden. bleibt nur die rechtliche frage, wie wetter.de das sieht.
    Dateien
    • WeatherForecastDemo.zip

      (122,39 kB, 384 mal heruntergeladen, zuletzt: )
    • Weather.zip

      (72 kB, 394 mal heruntergeladen, zuletzt: )
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    OK
    meine anwendung ist fast fertig. der code basiert auf dem pronzip von spaceyX.
    mein letztes problem ist noch: wie kann ich einen wert in ein "textfeld" von einer webseite eingeben , enter drücken und die webseite,auf die man danach weiter geleitet wird als adresse speichern - alles per vb.net?

    das mit dem wert in der webseite eingeben ist die suchzeile auf der adresse "wetter.com" ;)

    wincrash
    (\_/) Das ist Hase.
    (O.o) Kopiere Hase in deine Signatur
    (> <) und hilf ihm so auf seinem Weg zur Weltherrschaft.