Entwickler-Ecke

Internet / Netzwerk - Forumular automatisch füllen Twebbrowser


Andi1982 - So 19.03.06 19:16
Titel: Forumular automatisch füllen Twebbrowser
Hallo,

ich habe im TWebBrowser eine Seite dargestellt auf dem sich ein Formular befindet. Ich würde dieses Formular gerne automatisch ausfüllen und den Submit butten drücken.

Habe hier leider nichts gefunden ob das überhaupt möglich ist. Vorallem wie ich den submit-Button betätigen kann.

Hat da jemand eine idee??

Das formular der seite sieht so aus:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
<form name="units" action="seite.php?dorf=52485&screen=place&try=confirm" method="post">
<input name="anzahl1" type="text" size="5" tabindex="1" value="" />
<input name="anzahl2" type="text" size="5" tabindex="2" value="" />
<input name="anzahl3" type="text" size="5" tabindex="1" value="" />
<input type="text" name="teil1" value="" size="2" />
<input type="text" name="teil2" value="" size="2" />
<input type="text" name="teil3" value="" size="2" />
<input class="attack" name="attack" type="submit" value="Aktion1" style="font-size: 10pt;" />
<input class="support" name="support" type="submit" value="Unterstützen" style="font-size: 10pt;" />
</form>


Könnte man sich vielleicht irgendwie durch simulierte Tastendruck durchhängeln?

Hoffe auf gute Anregungen.

Viele grüße andi


MSCH - So 19.03.06 19:20

hallo, für's nächste Mal; schau bitte vorher im Forum via Suche,

look here: http://www.delphi-forum.de/viewtopic.php?t=57611&highlight=

grez
msch


Andi1982 - So 19.03.06 19:40

Hi,
danke für den Link. Habe vorher auch gesucht, aber kann mit diesem Thread nicht wirklich was anfangen. Kann das irgendwie nicht auf die TWebBrowser-Komponente umsetzen...


MSCH - So 19.03.06 19:46

also,
im Prinzip ist es einfach.
Der Webbrowser als auch das Pedant DhtmlEdit implementieren die DOM. (oder heist es das DOM?)
Über diese Schnittstelle (Interface) hast du Zugriff auf alle
"Felder" etx. also auf <p>, auf <Intput> und so weiter.

damit steht dir dann offen, die werte zu ändern.

grez
msch


Andi1982 - So 19.03.06 20:54

Ich habe es jetzt mal mit einer funktion probiert die ich hier im forum gefunden habe:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
function TForm1.FillForm(WebBrowser: TWebBrowser; FieldName: string; Value: string): Boolean;
var
  i, j: Integer;
  FormItem: Variant;
begin
  Result := False;
  //no form on document
  if WebBrowser.OleObject.Document.all.tags('form').Length = 0 then
  begin
    Exit;
  end;
  //count forms on document
  for I := 0 to WebBrowser.OleObject.Document.forms.Length - 1 do
  begin
    FormItem := WebBrowser.OleObject.Document.forms.Item(I);
    for j := 0 to FormItem.Length - 1 do
    begin
      try
        //when the fieldname is found, try to fill out
        if FormItem.Item(j).Name = FieldName then
        begin
          FormItem.Item(j).Value := Value;
          Result := True;
        end;
      except
        Exit;
      end;
    end;
  end;
end;


aber bei dem "if WebBrowser.OleObject.Document.all.tags('form').Length = 0" findet er 0 und springt raus!

Habe allerdings zu testzwecken mal den header aus der html-datei genommen und nur die form drinnen gelassen. Dann gings! So sieht der orginale Kopf der html-datei aus:


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" />
<title>Eggenstein (16:66:10) - Die Stämme</title>
<link rel="stylesheet" type="text/css" href="stamm1141419484.css" />
<link rel="stylesheet" type="text/css" href="overview.css" /><script type="text/javascript">
//<![CDATA[
if(!top || top.frames.length < 2 || top.location.host!="ds5.die-staemme.de") { top.location="staemme.php?village=52485&screen=place";}
//]]>
</script>
<script src="script.js?1141475934" type="text/javascript"></script>
<script src="menu.js?1141475934" type="text/javascript"></script>
</head>
<body>


fällt jemandem was auf???? An dem XML liegt es aber nicht, das hatte ich bei meinem test auch mit drinnen...


Andi1982 - Mo 20.03.06 08:26

Ich könnte auch jemandem den ganzen quelltext der Seite zukommen lassen. Allerdings wäre dies ein bisschen zu groß um hier zu posten.


MSCH - Di 21.03.06 17:02

nutzt du Frames?

grez
msch


Andi1982 - Di 21.03.06 17:34

nein, eigentlich nicht! habe aber für dieses formular jetzt eine möglichkeit gefunden!

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
procedure TForm1.Button3Click(Sender: TObject);
var
  Webform : variant ;
begin
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('spear').value := Edit4.Text;
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('sword').value := Edit5.Text;
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('axe').value := Edit6.Text;
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('spy').value := Edit7.Text;
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('light').value := Edit8.Text;
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('heavy').value := Edit9.Text;
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('ram').value := Edit10.Text;
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('catapult').value := Edit11.Text;
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('snob').value := Edit12.Text;
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('attack').click;
end;


aber jetzt habe ich ein neues formular das leider keinen name-tag hat auf der nächsten seite...

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
<form action="game.php?village=52485&screen=place&action=command&h=f76c" 

method="post" onSubmit="this.submit.disabled=true;">
<input type="hidden" name="attack" value="true">
<input type="hidden" name="con" value="16">
<input type="hidden" name="sec" value="65">
<input type="hidden" name="sub" value="9">
<input type="hidden" name="spear" value="0">
<input type="hidden" name="sword" value="0">
<input type="hidden" name="axe" value="0">
<input type="hidden" name="spy" value="10">
<input type="hidden" name="light" value="30">
<input type="hidden" name="heavy" value="0">
<input type="hidden" name="ram" value="0">
<input type="hidden" name="catapult" value="0">
<input type="hidden" name="snob" value="0">
<input name="submit" onClick="" type="submit" value="» OK «" style="font-size: 10pt;">
</form>


da müsste ich nur submitten, aber das geht auch nicht :( ich versuche es so:    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item(0).Elements.item('submit').click;
natürlich erst wenn der browser auch fertig geladen hat! darauf habe ich geachtet!

hat da jemand eine idee??


Andi1982 - Di 21.03.06 22:22

Habe es jetzt nochmal ausprobiert... zuerst hatte ich es so:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
procedure TForm1.Button5Click(Sender: TObject);
begin
//Erstes Formular:
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('spear').value := Edit4.Text;
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('sword').value := Edit5.Text;
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('axe').value := Edit6.Text;
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('spy').value := Edit7.Text;
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('light').value := Edit8.Text;
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('heavy').value := Edit9.Text;
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('ram').value := Edit10.Text;
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('catapult').value := Edit11.Text;
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('snob').value := Edit12.Text;
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('attack').click;

//Pause 
    WaitBrowser(WebBrowser1);
//Zweites forumular:
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item(0).Elements.item('submit').click;
end;

.
.
.

procedure TForm1.WaitBrowser(eWebBrowser: TWebBrowser);
begin
  Repeat
    Sleep(50);
    Application.ProcessMessages;
  Until (eWebBrowser.ReadyState = READYSTATE_COMPLETE);
end;


dachte eigentlich die WaitBrowser ist ok! Aber beim click auf das zweite formular knallts! wenn ich das aber auf zwei buttons verteile und erst den ersten und dann den zweiten klicke gehts!

SO:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
procedure TForm1.Button3Click(Sender: TObject);
var
  Webform : variant ;
begin
  // erstes Formular abschicken
//  SubmitWebForm(WebBrowser1.OleObject.document.forms.Item(0));
//  WebBrowser1.OleObject.Document.forms.Item(0).Item('spear').Value := '10';
//  FillForm(WebBrowser1, 'spear', '10');
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('spear').value := Edit4.Text;
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('sword').value := Edit5.Text;
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('axe').value := Edit6.Text;
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('spy').value := Edit7.Text;
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('light').value := Edit8.Text;
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('heavy').value := Edit9.Text;
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('ram').value := Edit10.Text;
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('catapult').value := Edit11.Text;
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('snob').value := Edit12.Text;
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('attack').click;
    WaitBrowser(WebBrowser1);
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item(0).Elements.item('submit').click;
end;


Weiß jemand wie ich das in einen button bekommen könnte?? mit einer gescheiten pause dazwischen ??


Andi1982 - Do 23.03.06 17:42

habe was gefunden wo einigermaßen funktioniert... siehe hier! [http://www.delphipraxis.net/topic63316_twebbrowser+problem.html]

nur das mit der "if pDisp = WebBrowser1.DefaultInterface then" funktioniert nicht wirklich... der läuft da nicht auf true...


Andi1982 - Fr 24.03.06 08:15

Inzwischen sieht mein Code so aus:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
procedure TForm1.Button5Click(Sender: TObject);
begin
  // erstes Formular abschicken
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('spear').value := Edit4.Text;
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('sword').value := Edit5.Text;
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('axe').value := Edit6.Text;
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('spy').value := Edit7.Text;
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('light').value := Edit8.Text;
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('heavy').value := Edit9.Text;
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('ram').value := Edit10.Text;
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('catapult').value := Edit11.Text;
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('snob').value := Edit12.Text;
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item('units').Elements.item('attack').click;
    repeat
      Application.ProcessMessages;
    until DocumentLoaded;
    WebBrowser1.OleObject.Document.Frames.item('MAIN').Document.Forms.item(0).Elements.item('submit').click;
end;

procedure TForm1.WebBrowser1BeforeNavigate2(Sender: TObject;
  const pDisp: IDispatch; var URL, Flags, TargetFrameName, PostData,
  Headers: OleVariant; var Cancel: WordBool);
begin
//  if pDisp = WebBrowser1.DefaultInterface then
    DocumentLoaded := false;
end;

procedure TForm1.WebBrowser1DocumentComplete(Sender: TObject;
  const pDisp: IDispatch; var URL: OleVariant);
begin
//  if pDisp = WebBrowser1.DefaultInterface then
    DocumentLoaded := true;
end;


Das geht in ca. 80% der Fällen gut! In den anderen bekommt er beim submit des zweiten Formulars noch einen Zugriffsfehler. Ich denke das liegt an einem Werbebanner der mit Java-script zwischendurch neu geladen wird. Wenn der das DocumentLoaded auf true setzt obwohl das submit des Formulars noch nicht fertig war dann krachts wohl.

Hat jemand eine Idee wie ich das in den griff bekommen könnte??


Andi1982 - Fr 24.03.06 10:21

Oh ich bin so blöde :nut: Habe gerade gesehen dass der oben angesprochene Banner in einem Extra frame ist...

Kann ich irgendwie abfragen welches frame den schalter "DocumentLoaded" auf false setzt? Dann könnte ich beim Setzen auf true wieder nur das frame auf true setzen lassen wo auch auf false gesetzt hat...

Nur wie geht das???


Andi1982 - Mo 27.03.06 07:38

Lösung:

Also ich habe jetzt eine Möglichkeit gefunden das ganze mit dem Werbebanner in den Griff zu bekommen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
procedure TForm1.WebBrowser1BeforeNavigate2(Sender: TObject;
  const pDisp: IDispatch; var URL, Flags, TargetFrameName, PostData,
  Headers: OleVariant; var Cancel: WordBool);
begin
    CurWebBrowser := pDisp as IWebBrowser;
    DocumentLoaded := false;
end;

procedure TForm1.WebBrowser1DocumentComplete(Sender: TObject;
  const pDisp: IDispatch; var URL: OleVariant);
var
    TopWebBrowser: IWebBrowser;
    Startseite: String;
begin
  TopWebBrowser := pDisp as IWebBrowser;
  if TopWebBrowser = CurWebBrowser then
    DocumentLoaded := true;
end;


Eigentlich hätte ich früher darauf kommen können, hätte aber nicht gedacht dass das funktioniert :) Hoffe das hilft irgendwann mal jemandem weiter...