WebBrowser nach ID suchen und im selben Block nach Classname

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 6 Antworten in diesem Thema. Der letzte Beitrag () ist von Radinator.

    WebBrowser nach ID suchen und im selben Block nach Classname

    Guten Abend,

    ich habe mich vor kurzem viel mit dem WebBrowser beschäftigt und ich war mir sicher, ich hätte es raus. Aber irgendwie verstehe ich hier mal wieder die Logik nicht. Ich finde überhaupt nichts im Internet und langsam ermüdet es mich auch.



    VB.NET-Quellcode

    1. ​For Each element As HtmlElement In WebBrowser1.Document.GetElementsByTagName("h2")
    2. If element.GetAttribute("classname") = "branded-page-module-title shelf-title-cell" Then
    3. RichTextBox1.Text &= vbCrLf & (element.GetAttribute("data-sessionlink"))
    4. End If
    5. Next


    Dies ist nur ein Beispiel Code. Ich spreche hier keine bestimmte Seite an, die Seiten variieren sich je nach Übung für mich. Zurzeit jedoch bin ich aktivsten auf der Seite "Youtube.com". Das ist jedoch irrelevant.

    Ihr seht im Code, dass ich eine For Each Schleife erstellt habe, die durch alle Elemente mit dem TagName "div" durchgeht. Eine Abfrage habe ich natürlich auch für den richtigen Attribute gesetzt, damit er dort stoppt und meinen Code ausführen kann. Mein Code ist jedoch eine weitere Abfrage nach einem Attribute und zwar von "Style" jedoch im gleichen "Block", wenn man das so sagen kann(für mich ein Block = z.B alles zwischen "div"). Aber er ist ja immer noch auf der Zeile fokussiert, wo er das Attribute "branded-page-module-title shelf-title-cell" gefunden hat. Wie soll ich ihm aber sagen, dass er nun nach dem data-sessionlink im selben Block suchen soll?

    VB.NET-Quellcode

    1. ​Dim theElementCollection As HtmlElementCollection = Nothing
    2. theElementCollection = WebBrowser1.Document.GetElementsByTagName("h2")
    3. For Each curElement As HtmlElement In theElementCollection
    4. If InStr(curElement.GetAttribute("classname").ToString, "branded-page-module-title shelf-title-cell") Then
    5. RichTextBox1.Text &= (curElement.GetAttribute("InnerText"))
    6. End If
    7. Next


    Sowas habe ich auch versucht. Erfolglos. Ich bekomme als "InnerText" nur einen " " returned.
    Ich habe des aber irgendwie mal gemacht, nur habe ich meine alten Projekte nicht mehr, um nachzuschauen. Hat da jemand eine Lösung?
    Wenn ich eine Frage stelle, habe ich sie bereits gegooglet. Ja, es kommt vor, dass ich die Antwort übersehe. Ja, es kommt vor, dass ich sie nicht verstehe. Deshalb bin ich hier. Wenn dies eure Frage war, dann antwortet bitte nicht. Es stiehlt sämtliche Motivation.
    Nabend Sekki,

    das data-sessionlink-Attribut ist teil des Anchor-Elements innerhalb des Div-Elements, nicht des Div-Elements selbst. Es könnte also in etwa so funktionieren:

    VB.NET-Quellcode

    1. RichTextBox1.Text &= element.GetElementsByTagName("a")(0).GetAttribute("data-sessionlink")


    Ich würde allerdings schon von vornherein auf den Classname der Überschrift zwei abzielen und gar nicht erst nach Tagnames suchen. Der genannte ClassName scheint bei Youtube recht eindeutig. Dann sollte (ohne Fehlerbehandlung) schon das funktionieren:

    VB.NET-Quellcode

    1. RichTextBox1.Text &= vbCrLf & WebBrowser1.Document.GetElementsByClassName("branded-page-module-title shelf-title-cell")(0).GetElementsByTagName("a")(0).GetAttribute("data-sessionlink").ToString


    Viele Grüße
    derHoepp
    @derHoepp
    Vorab: Danke dir für diese ausführliche Antwort. Ich konnte mir daraus auf jeden Fall ein Stückchen entnehmen. Bei mir hat es nun mit dem folgenden Code geklappt, jedoch habe ich dort noch ein weiteres Problem. (ich musste weiterhin nach dem Tagname suchen, weil bei mir "GetElementsByClassname" nicht existiert)

    VB.NET-Quellcode

    1. For Each Element As HtmlElement In WebBrowser1.Document.GetElementsByTagName("div")
    2. If Element.GetAttribute("id").Contains("akte_") Then
    3. RichTextBox1.Text &= Element.GetElementsByTagName("div")(0).GetAttribute("style").ToString & vbCrLf
    4. End If
    5. Next


    Dies ist nun eine andere Seite, ich hoffe, es stört dich nicht. Das Prinzip bleibt ja gleich. Deine Variante funktioniert wunderbar, jedoch bekomme ich bei diesem Code(aber nur bei dem Attribute "style", die anderen funktionieren) folgendes raus: "System.__ComObject". Der Inhalt von Style ist:

    VB.NET-Quellcode

    1. style="background:url(http://xxxxxxxxxxxxxxx.de/akten/akte1.gif)"


    Bitte nicht über die Zensur wundern, ich arbeite seit einer Weile an einem Projekt mit ein paar Kollegen, wo ich für den Programmteil zuständig bin und die "Akten" sind öffentlich einsehbar.

    Nun habe ich noch eine weitere wichtige Frage, weil ich nicht weiß, wie man das nennt um mich zu erkundigen:

    VB.NET-Quellcode

    1. RichTextBox1.Text &= Element.GetElementsByTagName("div")(0).GetAttribute("style").ToString & vbCrLf


    Mit dem "(0)" nach dem Tag kann ich erst "GetAttribute" nutzen. Was heißt also dieses "(0)"? Also, wie nennt man sowas und was genau macht es?


    mox schrieb:

    zum parsen von html code das html agility pack benutzen


    Das hast du mir, glaube ich, schon mal vorgeschlagen. Mein Problem war jedoch, dass ich den WebBrowser Control nutze, weil im Programm eine Übersicht über die Seite verfügbar sein muss. Und ich weiß leider nicht, wie ich des beim WebBrowser Control anwende.(falls des überhaupt geht)

    //EDIT:
    Ich habe nun eine Lösung gefunden, jedoch möchte ich sie ungerne nutzen. Etwas eleganteres wäre super:

    VB.NET-Quellcode

    1. Dim iStartPos As Integer = Element.OuterHtml.IndexOf("style=""background""") + ("style=""background""").Length
    2. Dim iEndPos As Integer = Element.OuterHtml.IndexOf(")", iStartPos)
    3. Dim s As [String] = Element.OuterHtml.Substring(iStartPos, iEndPos - iStartPos)
    4. Dim Splits = s.Split("("c)
    5. s = Splits(1).Replace("""", "")

    Wenn ich eine Frage stelle, habe ich sie bereits gegooglet. Ja, es kommt vor, dass ich die Antwort übersehe. Ja, es kommt vor, dass ich sie nicht verstehe. Deshalb bin ich hier. Wenn dies eure Frage war, dann antwortet bitte nicht. Es stiehlt sämtliche Motivation.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Sekki“ ()

    Moin Sekki,

    ich kann dir leider nicht mehr ganz folgen. Mir scheint derzeit, als ändere sich deine Anforderung von Post zu Post :) Die konkrete Frage kann ich dir aber gern beantworten:
    Was heißt also dieses "(0)"?

    Die getElementsByTagName()-Methode gibt dir eine Collection mit den Elementen zurück https://msdn.microsoft.com/en-us/library/system.windows.forms.htmldocument.getelementsbytagname(v=vs.110).aspx
    Um auf ein einzelnes Member einer Collection zuzugreifen, kannst du im Allgemeinen einen numerischen Index angeben. Und genau das machst du mit (0). Du greifst auf das erste Objekt der Collection zu. Konkret handelt es sich bei der Rückgabe um eine HTML-ElementsCollection (msdn.microsoft.com/en-us/libra…collection(v=vs.110).aspx). Eigentlich nutzt du implizit die .Item()-Property, die eine String und eine Integer Überladung hat.

    Viele Grüße
    derHöpp
    @derHoepp
    Danke für die Information! Jetzt verstehe ich des auf jeden Fall ein wenig mehr.

    Jedenfalls: Meine Frage hat sich geändert, weil meine eigentliche Frage sich bereits dank dir beantwortet hat. Meine zweite Frage war eine separate Frage, welche auf ein Problem hinweist, welche mit der ersten Frage entstanden ist. Eh...

    1. Ich stelle dir eine Frage
    2. Deine Antwort funktioniert super
    3. Jedoch gibt deine funktionierende Antwort bei "style" nicht das Attribute als String aus, sondern als "System.__comObject"

    Und meine zweite Frage war nun, wie ich dieses "System.__comObject" umwandeln kann in einen String, welchen ich lesen kann! :'3
    Wenn ich eine Frage stelle, habe ich sie bereits gegooglet. Ja, es kommt vor, dass ich die Antwort übersehe. Ja, es kommt vor, dass ich sie nicht verstehe. Deshalb bin ich hier. Wenn dies eure Frage war, dann antwortet bitte nicht. Es stiehlt sämtliche Motivation.

    Sekki schrieb:

    InStr(curElement.GetAttribute("classname").ToString
    Nimm bitte die .Contains() Methode! InStr() ist 1.) Veraltet und 2.) Teil des VB Namespaces

    Sekki schrieb:

    Jedoch gibt deine funktionierende Antwort bei "style" nicht das Attribute als String aus, sondern als "System.__comObject"
    Könntest du den Code, den du dazu verwendest, bitte mal posten?


    Lg Radinator
    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell