Auf Controls einer Website zugreifen ohne die ID zu kennen?

  • VB.NET

Es gibt 20 Antworten in diesem Thema. Der letzte Beitrag () ist von Benjamin.

    Auf Controls einer Website zugreifen ohne die ID zu kennen?

    Hallo liebe VBler,
    ich habe folgendes Problem:
    Ich möchte ein Programm schreiben, mit welchem ich diverse Browseraktivitäten simulieren kann.
    Also kurz gesagt einen Bot schreiben.
    Ich kenne die Methode:

    VB.NET-Quellcode

    1. Webbrowser1.Document.GetElementById("ID des Elements").InvokeMember("click")


    Das .InvokeMember nurmal so als Beispiel.
    Jetzt habe ich das Problem, dass ich z.B. von manchen Buttons nicht die ID kenne.
    Meine Frage:
    Wie kann ich mit diesen Steuerelementen trotzdem "kommunizieren" ;)
    Vielen Danke schonmal im Voraus ;)
    Ok... aber gibt es da gar keine andere Möglichkeit? Die Controls haben ja auch noch andere Klassifizierungen. Und wenn man die Controls nur über die ID ansprechen kann, dann muss das die Website ja auch irgendwie so machen. Also muss jedes Steuerelement eine ID haben, oder habe ich da was falsch verstanden? :D
    Naja wie auch immer Danke für die schnelle Antwort :thumbsup:
    Les mal den Quellcode einer Website aus, da steht überall eine ID bzw die ganzen Eigenschaften zu den Control.
    Die Webseite muss dann ja auch zum Beispiel per CSS wissen wie was heißt.

    Du kannst alle Controls nach Type mit ner Schleife durch gehen und Auflisten lassen.
    Habe ich alles schon versucht ;)
    Ich benutze Google Chrome und da gibt es ja auch die "Element untersuchen" Funktion.
    Allerdings bin ich dort auch nicht fündig geworden.
    Und das mit der Schleife habe ich nicht ganz verstanden ;)
    Bin noch ein rechter Neuling.
    Könntest du mir dafür ein Code-Beispiel verfassen?

    Benjamin schrieb:

    Jetzt habe ich das Problem, dass ich z.B. von manchen Buttons nicht die ID kenne.
    Das ist ein zu umfangreiches Thema: das WebBrowser Control gibt Dir ein HTMLDocument zurück, dessen Properties und Methoden schaust Du Dir am besten hier an: HtmlDocument-Klasse

    Meist verwendete Properties: All, Body, Forms, Links
    Meist verwendete Methoden: GetElementByID, GetElementsByTagName

    Die meisten Methoden/Properties liefern HtmlCollections zurück die Du durchlaufen und speziell nach Deinen Kriterien (Name, Klasse, Attribute, Values) auswählen kannst.

    n1nja schrieb:

    Ohne die ID´s zu wissen kannst du nichts machen?!
    Ziemlicher Schmarrn.
    Nochmals eine Frage ?(
    Mit der Methode GetElementsByTagName kann ich damit nur die "Anzahl" der Elemente anzeigen lassen oder auch die "Namen"?
    Entschuldigung falls ich hier ein paar "offensichtliche" Fragen in den Raum werfe, aber für mich ist das Ganze noch rechtes Neuland :D

    Benjamin schrieb:

    Mit der Methode GetElementsByTagName kann ich damit nur die "Anzahl" der Elemente anzeigen lassen oder auch die "Namen"?
    Mehr als das.

    Mit dem HtmlDocument erhälst Du vollen Zugriff auf das Document Object Model der Webseite. Mit GetElementsByTagName bekommst Du also eine Liste von HTML-Elementen mit einem definierten TagName zurück, die wiederum eigene Unterelemente haben können etc, etc.

    .GetElementByTagName("Form") gibt Dir also als Beispiel die gesamte Liste der 'Form's zurück, die wiederum Buttons und andere Elemente enthlten können. Man hangelt sich also möglichst strukturiert durch einen Elementenbaum durch.

    Die Collection hat wiederum eine interessante Methode 'GetElementsByName": wenn Dein Button also statt einer ID einen Namen hat (hat er meistens), und dieser innerhalb der Form auch eindeutig ist, so kannst Du ziemlich schnell dorthin kommen.

    Mach im Zweifelsfall ein Beispiel: das ist immer noch einfacher als Dir das DOM in diesem Post zu erklären.
    Vielen Dank :D
    Werd ich morgen (heute) gleich mal ausprobieren :D Hört sich auf jeden Fall schonmal sehr vielversprechend an. Und ja ich glaube einen Namen haben die Buttons. Ein Beispiel werd ich morgen (heute) gleich mal hochladen wenn ich zuhause bin :D
    Es wäre ganz gut gewesen die Deklaration der umschliessenden HTML-Form mit aufzunehmen, da diese meist eine ID hat. Dann kann man per GetElementsByTagName("Input") alle Input Elemente holen. Das ist die normale Vorgehensweise.

    Aber es geht auch so (wenn Dein HTML Code richtig ist):

    VB.NET-Quellcode

    1. ' nur zur kürzeren Schreibweise und Klarstellung dass es ein HTMLDocument ist
    2. Dim doc As HtmlDocument = webbrowser1.Document
    3. ' das Element mit der ID 'UnitBox' ermitteln
    4. Dim divUnitBox As HtmlElement = doc.GetElementById("UnitBox")
    5. ' der button ist das 1. Element danach auf der gleichen Ebene
    6. Dim button As HtmlElement = divUnitBox.NextSibling
    7. ' nur als Test ob wir den richtigen haben
    8. Debug.Print(button.OuterHtml)

    Dass Du auf das Document.Completed Ereignis warten musst um ein gültiges HTMLDocument zu bekommen, ist Dir hoffentlich klar.

    natürlich kann man das Ganze auch kürzer schreiben: Dim button As HtmlElement = doc.GetElementById("UnitBox").NextSibling
    Dass ich warten muss ist mir klar ;) Ich mache das mit einer Do While Webbrowser1.ReadyState <> Readystate.Complete Schleife.
    Dankeschön für den Code, allerdings habe ich den noch nicht wirklich verstanden.
    Ich denke ich weiß so grob was du meinst, aber kann dem Ganzen noch nicht wirklich folgen.
    Bei deinem Code tut sich allerdings noch nichts. Ich glaube aber, dass es daran liegt, dass der Button nicht das nächste Element auf dieser Ebene ist (Sofern ich das richtig verstanden habe.).
    Woran genau erkennt man denn das nächste Element auf der gleichen Ebene? Und was mache ich wenn es mehrere Elemente auf der selben Ebene gibt, aber das gewünschte Element nicht das Nächste ist?

    Ich habe allerdings nochmal eine Frage ;)
    Ist es möglich festzustellen, ob ein Element sichtbar ist oder nicht?
    Denn bei der Website ist es so, dass Steuerelemente sichtbar sind und dann anderen "Platz machen".
    Der Quelltext bleibt jedoch jedes mal gleich.
    Das liegt vermutlich daran, dass die Website nicht neu geladen wird. Also muss der Quelltext meines Erachtens ja gleich bleiben oder?

    Benjamin schrieb:

    Ich mache das mit einer Do While Webbrowser1.ReadyState <> Readystate.Complete Schleife
    Wenn kein Application.Doevents dazwischen ist, so wird das kaum funktionieren und auch dann ist es zweifelhaft.

    Benjamin schrieb:

    Ich glaube aber, dass es daran liegt, dass der Button nicht das nächste Element auf dieser Ebene ist
    Deshalb auch meine Einschränkung ob Dein zitierter HTML-Code richtig wäre, sieht nicht danach aus.

    Benjamin schrieb:

    Denn bei der Website ist es so, dass Steuerelemente sichtbar sind und dann anderen "Platz machen".
    Der Quelltext bleibt jedoch jedes mal gleich.
    Woher willst Du das wissen ? Der Quelltext kann jeder Zeit (und wird oft) per Javascript nachgeladen werden, willkommen bei Web 2.0.

    Insofern ist ein "Programm zur Simulation von Browseraktivitäten" auf Basis des WebBrowser Controls auch meist ziemlich frustrierend. Der bessere Weg führt über die HttpWebRequest Klasse
    Das Application.DoEvents ist schon dazwischen :D hab ich nur vergessen dazu zuschreiben ;) und bis jetzt hat es wunderbar funktioniert.

    Welche Teile des Quelltexts brauchst du dann? Also woran erkenne ich die "umschließende HTML-Form"?
    Habe von HTML gar keine Ahnung :D

    Und bei dem Quelltext bin ich mir sicher.
    Ich habe mir eine Anwendung erstellt die 2 Strings vergleicht und habe bei jedem mal, als neue Steuerelemente angezeigt wurden, mir den Quelltext neu anzeigen lassen.
    Das Ergebnis war, dass der Quelltext immer gleich war.

    Benjamin schrieb:

    Das Application.DoEvents ist schon dazwischen :D hab ich nur vergessen dazu zuschreiben ;) und bis jetzt hat es wunderbar funktioniert.
    Wenn Du meinst ...
    Wenn Du das DocumentCompleted Event nicht benutzt, so weisst Du ja ganichst über das Verhalten der Seite.

    Benjamin schrieb:

    Habe von HTML gar keine Ahnung
    Dann solltest Du das tunlichst nachholen: -> SelfHtml.Org

    Benjamin schrieb:

    Ein <form> und ein </form> gibt es in dem Quelltext nicht!
    Dann macht ein Input-Element wohl auch ncht sonderlich viel Sinn - oder ?

    Sry, aber Du scheinst ja selber sehr zuversichtlich zu sein was Deine Analysen angeht, aber ich glaube nicht einmal die Hälfte davon.
    Ja ich habe das mit einem kleinen Programm überprüft :D
    Aber ich kann auch das Ereignis verwenden, wenn du meinst, dass das besser ist ;)

    Über HTML habe ich mir ein Buch bestellt also das wird nachgeholt ;)

    Ja da bin ich mir ziemlich sicher ;) Ich habe im Quelltext nach "form" gesucht, aber es wurde nichts gefunden also scheint es das nicht zu geben :D
    PS: Ich lasse mich gern eines besseren belehren ;)