Laden...

WebBrowser-Control: Formular füllen/Button klicken

Erstellt von Merti_berg vor 15 Jahren Letzter Beitrag vor 14 Jahren 6.175 Views
M
Merti_berg Themenstarter:in
91 Beiträge seit 2008
vor 15 Jahren
WebBrowser-Control: Formular füllen/Button klicken

Hallo, Ich hab mal wieder ein Problem. Ich würde gerne ein Programm schreiben was auf eine Internet-Seite zugreift und da Textfelder ausfüllt/Buttons klickt. Ich habe mich heut schon den ganzen Tag dazu eingelesen aber leider ohne großen Erfolg.

Ich bin nun soweit das dass webbrowser Element in meiner Form auf eine Webseite geht und dort etwas in eine Textbox schreibt und dann einen Button klickt.
Die Url bestimme ich so:


private void button1_Click(object sender, EventArgs e)
        {
            webBrowser1.Url = new Uri("http://" + textBox1.Text +"/");
            webBrowser1.Refresh();            
        }

wenn ich aber diese 2 Zeilen mit zu button2_Click(...) hinein nehme bringt er mit jedes mal: "Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt."

Ich muss immer erst button1 betätigen und dann button2 mit folgendem code:


private void button2_Click(object sender, EventArgs e)
        {
             for (int i = 0; i < webBrowser1.Document.Forms.Count; i++)
            {
                HtmlElement element = webBrowser1.Document.Forms[i].All[i];

                if (element != null && element.GetAttribute("value").Equals(""))
                {
                    webBrowser1.Document.All["q"].SetAttribute("value", textBox2.Text);
                    webBrowser1.Document.Forms[i].InvokeMember("submit");  
                }
            }
        }

Wenn ich es so mache funktioniert alles, er läd die Seite im webbrowser in der Form und gibt mir dann in die Textbox ein das was bei mir in textbox2 steht.

Vielleicht hat da jemand einen Tip für mich.

Ein weiteres Problem ist das Button anklicken, dies funktioniert hier zwar aber wenn ich zb. auf einer Webseite 2 Buttons habe wie spreche ich dann einen von beiden an? Ich sage bei meinem Code bloß das er das "submit" ausführen soll aber nicht für welchen Button. 🤔

Wäre nett wenn mir das jemand nochmal erklären könnte.

Vielen Dank schonmal.

82 Beiträge seit 2009
vor 15 Jahren

Ich denke mal, du bekommst die Exception, weil die Seite noch nicht fertig geladen ist, während du die Elemente anzusprechen versuchst. Pack den Code von Button_2 also einfach in den EventHandler vom DocumentCompleted-Event und dann müsste es auch mit einem Button gehen.
Und um eine speziellen Button ansprechen zu können musste dir mal den Quellcode der HTML-Seite anschauen und gucken, ob du den irgendwie über ein bestimmtes Attribut (id, value, etc) identifizieren kannst.

Diskordianer schwimmen nicht gegen den Strom - sie klettern aus dem Fluss! Ein Mathematiker ist ein Mensch, der einen ihm vorgetragenen Gedanken nicht nur sofort versteht, sondern auch weiß auf welchem Denkfehler er beruht
M
Merti_berg Themenstarter:in
91 Beiträge seit 2008
vor 15 Jahren

Danke, das mit dem Document_completed hat funktioniert.

bzgl. der Buttons, als Beispiel jetzt mal google, es gibt ja einmal den Button Google-Suche und auf gut Glück

HTML Code:


<input type="submit" value="Google-Suche" name="btnG"/>
<input type="submit" value="Auf gut Glück!" name="btnI"/>

Wenn ich es so mache


webBrowser1.Document.Forms[i].InvokeMember("submit");

Klickt er "Google Suche" an, wenn ich jetzt zb will das er "Auf gut Glück" anklickt hab ich keine Ahnung wie ich das anstelle...

Danke schonmal!

D
2 Beiträge seit 2009
vor 15 Jahren

hallo,

um einen anderen button anzuklicken musst du nur den namen von dem button wissen und dann per InvokeMember("Click") anklicken lassen 😉

dass würde dann in deinem fall so aussehen:

webBrowser1.Document.Forms[i].All["btnI"].InvokeMember("Click");

mfg
davi

D
2 Beiträge seit 2009
vor 15 Jahren

Jedoch habe ich jetzt auch eine frage zu diesem thema gg 😃

ich habe jetzt auch einen ganz normalen webbrowser erstellt und möchte über ihn einfach gesagt nacheinander auf meheren seiten verschiedene formulare ausfüllen.

jedoch wie kann ich in einer meiner eigenen funktion feststellen ob mein webbrowser schon fertig geladen hat um die elemente ansprechen zu können?

es viel zu umständlich den ganzen code in den Code vom Event handler vom DocumentCompleted-Event des webbrowsers zu stecken, da ich später noch viel mehr formulare ausfüllen und buttons anklicken möchte...

meine urüberlegung war daher immer wenn der DocumentCompleted-Event handler losgeht ihn einfach nur ein bool umzuändern lassen das ich dann einfach per schleife und if abfrage in der anderen funktion abfrage und dann den code weitermachen lasse.
aber wenn ich diesen weg versuche dann ladet der ganze browser nie

private bool boolfinished = false;
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        { boolfinished = true; }
private void login()
{ for(;;)
   { if(boolfinished==true)
          bla bla bla...
   }
}

hier ladet mein webbrowser natürlich nicht weil die endlosschleife zu viel arbeit braucht...

also hab ich es mit ner while probiert

while(webBrowser1.IsBusy) { } bla bla bla...

funktioniert leider auch nicht... ich vermute wieder gleich wie bei der vorherigen variante, dass die schleife einfach zu aufwändig ist und der webbrowser daher dann nicht laden kann...

dann ist mir eingefallen:

System.Threading.Thread.Sleep(Convert.ToInt16(timerandom.NextDouble() * 1000));

timerrandon ist ne ganz normaler random gg

damit de zeit zu verzögern und nochmal abzufragen ob der brwoser bereits fertiggeladen hat... aber aus irgendeinem grund tut er hier auch nichts... ich nehme an, weil hier nicht nur die aktuelle funktion stillgelegt wird sondern das ganze programm?

schlussendlich hab ich mich dann doch für die möglichkeit entschieden den ganzen code in den eventhandler zu packen.. jedoch mit einer switch anweisung die sich auf eine variable die ich bevor ich den webbrowser neuladen lasse immer verändere...

nur jetzt mein absolut für mich nicht erklärbares problem..

case "login":
              System.Threading.Thread.Sleep(Convert.ToInt16(timerandom.NextDouble() * 1000));
              writeformular("name", "value", "wert");
              writeformular("name", "value", "wert");
              webBrowser1.Document.Forms[0].All["buttonname"].InvokeMember("Click");
              break;

wenn ich einen haltepunkt auf jede zeile setzt, sagt mir der debugger ja auch dass er die erste writeforumlar zeile noch ausführt, indem er dort stoppt. dann drück ich auf weiter, und die haltepunkte die in den drei nächsten zeilen sind nimmt er nicht an und stoppt auch nicht und das programm lauft wieder ganz normal... das heißt diese führt er auch nicht aus, und er klickt auch nicht auf den button...
für mich unverständlich da er auch keinen fehler auspruckt warum er diese zeilen des programms nicht behandelt...

wenn ich jetzt das gleiche nur umgekehrt schreibe:

case "login":
              System.Threading.Thread.Sleep(Convert.ToInt16(timerandom.NextDouble() * 1000));
              webBrowser1.Document.Forms[0].All["buttonname"].InvokeMember("Click");
              writeformular("name", "value", "wert");
              writeformular("name", "value", "wert");
              break;

und hier klickt er sowohl auf den knopf als füllt im nachhinein meine 2 felder aus... was auch durch die haltepunkte die ich hier wieder setzte bestätigt werden dass er jede zeile ausführt...

vlt kann mir das jemand erklären warum er in dem oben angeführten case auf einmal aufhört meine zeilen zum ausführen?
weiterhin wäre ich über eine sinnvolle lösung wie ich das hier lösen könnte, und welcher von den genannten lösungsansätzen der beste ist sehr erfreut 😃

mit freundlichen grüßen
davi

M
Merti_berg Themenstarter:in
91 Beiträge seit 2008
vor 15 Jahren

Hallo,

Ich habe nochmal 2 Fragen dazu.

  1. Wie realisiere ich es wenn man eine Java-script Funktion benutzen will? Also man kann den zb. Button nicht normal anklicken das es weiter geht sondern dann wird ein JavaScript ausgelöst. Ich hatte es irgendwo mal gelesen aber ich such schon die ganze Zeit find es aber nicht mehr...

  2. Wenn man einen Link/Button anklicken will der aber keiner ist, also dh. als Bsp Hier im Forum


<a href="logout.php">Abmelden</a>

wie sage ich in meinem C# Programm das er da drauf klicken soll? ich habe ja dafür keinen namen und keine methode wie zb. submit

Wäre nett wenn mir das nochmal jmd kurz erläutern könnte.

M
Merti_berg Themenstarter:in
91 Beiträge seit 2008
vor 14 Jahren

So, ich denke das gehört auch noch mit dazu deswegen mach ich nicht erst einen neues Thread auf.

Habe auf einer Seite mehrere Buttons:

<input class="input" type="submit" value="Neues Thema erstellen" accesskey="S"/>
<input class="input" type="submit" value="Vorschau" accesskey="P" name="preview"/>
<input class="input" type="reset" value="Zurücksetzen" accesskey="R"/>

Diese Buttons haben aber weder Namen, noch ID.

Wenn ich bloß diesem Befehl schreibe

WBrowser.Document.Forms[i].InvokeMember("submit");

Wird das Thema erstellt aber dann tritt ein Scriptfehler auf.

Kann ich den Button auch noch anders ansprechen, also das er wirklich den Button neues Thema anklickt? getelementsbyID geht ja nicht, habs zwar auch schon mit getelementsbytagname probiert aber da weiß ich nicht woran ich sehe ob es der richtige button ist.

also entweder ich brauch ne möglichkeit den Button direkt anzusprechen um zu verhindern das der Scriptfehler kommt ODER ich muss irgendwie die Warnungen abstellen. Das wäre jetzt mal mein Ansatz. Wäre nett wenn mir da nochmal jmd helfen könnte.

//Edit: Ok ich weiß wie man die Fehler ausschaltet aber ich würde trozdem gerne wissen wie man speziell den Button ansprechen kann 😃