Entwickler-Ecke

Internet / Netzwerk - Problem mit TWebbrowser


the-kecks - Di 23.06.09 18:18
Titel: Problem mit TWebbrowser
//threadtitel editiert (problem siehe unten)

hi,
ich soll ein programm schreiben mit dem ich einen kaufvorgang automatisiere. nun geht dieser über mehrere instanzen:
1. Link zum angebot (klick auf kaufen)
2. einloggen
3. kaufbestätigung (klick auf button)
4. ca. 10 sekunden warten wegen bearbeitung
5. letzte seite (in dieser Seiten-SourceCode ausgeben lassen)
welche komponente wäre dafür die richtige? mit IdHTTP hab ich schon gearbeitet, aber nicht in mehreren schritten. und TWebbrowser wäre doch auch gut oder?

mfg


Bernhard Geyer - Di 23.06.09 19:02

Ich empfehle hier eher TWebBrowser (Bzw. TEmbeddedWB) da hier auch Session-Handling gegeben ist was du bei IdHTTP vermutlich nach programmieren müsstes. Und evtl. benötigst du auch HTTPs was bei TWebBrowser und Co. "Out of the Box" funktioniert.


jaenicke - Di 23.06.09 19:21

Fast das einzige was mit TIdHttp nicht funktioniert sind Skripte, HTTPS, Cookiemanager usw. sind alles kein Problem und vorhanden.

Da aber die letzte Seite wohl ohnehin angezeigt werden soll, ist TWebBrowser sicherlich geeignet. Dann kann der Benutzer den Vorgang auch direkt sehen.

user profile iconthe-kecks hat folgendes geschrieben Zum zitierten Posting springen:
4. ca. 10 sekunden warten wegen bearbeitung
Sind die fest auf 10 Sekunden festgelegt?


the-kecks - Di 23.06.09 19:29

ok. Kannst du mir noch ein Tutorial für TWebBrowser empfehlen? hab kaum damit gearbeitet

mfg


jaenicke - Di 23.06.09 19:37

Leider ist die Seite, die ich da sonst immer poste offline, aber im Grunde ist da gar nicht so viel erst einmal zu sagen. Wichtig sind Navigate um eine Seite zu laden und das Ereignis OnDocumentComplete [http://www.swissdelphicenter.ch/de/showcode.php?id=1355] um nach dem Laden der Seite fortzusetzen.


the-kecks - Di 23.06.09 19:42

meine kunde möchte sich aber nicht die seite ausgeben lassen sondern ein element der seite, dass ich aus dem sourcecode auslesen möchte. und wie trage ich daten in edits ein und wie klicke ich auf buttons (bei webbrowser)? nein, die wartezeit ist nicht auf 10 sek festgelegt. kann ich das auch mit sowas machen wie on doccomplete? weil das is so ne ladeseite wo unten ne progressbar läuft

mfg


toms - Di 23.06.09 20:05

Suche bei Google WEBBROWSER CLICK BUTTON
Suche bei Google WEBBROWSER FILL FORM


the-kecks - Di 23.06.09 21:23

thx und wie kann ich mit TWebbrowser den quellcode einer seite ausgeben lassen? (am besten als string)

mfg


toms - Di 23.06.09 21:27

user profile iconthe-kecks hat folgendes geschrieben Zum zitierten Posting springen:
thx und wie kann ich mit TWebbrowser den quellcode einer seite ausgeben lassen? (am besten als string)

mfg


Google ;)


the-kecks - Mi 24.06.09 14:05

hab da ein problem:

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:
  var i2, j : Integer;
  begin
    Webbrowser1.Navigate(URL);
    while WebBrowser1.ReadyState <> READYSTATE_COMPLETE do application.processmessages;
    for i2 := 0 to WebBrowser1.OleObject.document.forms.Length-1 do
    begin
      for j := 0 to WebBrowser1.OleObject.document.forms.Item(i2).Length-1 do
      begin
        if WebBrowser1.OleObject.document.forms.Item(i2).Item(j).Name = 'loginControl_txt_email' then
        begin
          WebBrowser1.OleObject.document.forms.Item(i2).Item(j).Value := Memo2.lines[i];
        end;
        if WebBrowser1.OleObject.document.forms.Item(i2).Item(j).Name = 'loginControl_txt_pwd' then
        begin
          WebBrowser1.OleObject.document.forms.Item(i2).Item(j).Value := Memo3.lines[i];
        end;
        if (WebBrowser1.OleObject.document.forms.Item(i2).Item(j).Type = 'submit'and (WebBrowser1.OleObject.document.forms.Item(j).Id = 'loginControl_bt_continue'then
        begin
          WebBrowser1.OleObject.document.forms.Item(i2).Item(j).click;
        end;
      end;
    end;
  end;

hierbei passiert nichts...der scrollt zum email eingabe edit und dann passiert nix mehr :(

mfg


the-kecks - Do 25.06.09 20:20

weiß niemand weiter?

mfg


Lannes - Fr 26.06.09 15:27

Hallo,

doch, bestimmt :wink:

setz doch mal einen Haltepunkt in die Zeilen 11, 15 und 19.
Dann siehst Du ob der Code die Eingabefelder/den submit-Button überhaubt findet.

Ps.: enthält Memo2.lines[i] und Memo3.lines[i] auch Text?


the-kecks - Fr 26.06.09 16:04

oh mann manchmal...*peinlich*
der findet die objekte gar nicht.
hat das vll damit zu tun, dass die Objekte in einem Frame sind? muss ich den zuerst auswählen?

mfg


Delete - Fr 26.06.09 17:39

Guckst Du hier:
http://www.torry.net/samples/samples/internet/MiniWebbrowserDemo.zip


the-kecks - Fr 26.06.09 22:32

ok ich hab mich ejtzt mal ein bisschen mit frames beschäftigt:
//code update

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:
    Webbrowser1.Navigate('http://www.gamesload.de/de/mygamesload/kaufen.php?intIdGame=31044&partner=bbyd');
    while WebBrowser1.ReadyState <> READYSTATE_COMPLETE do application.processmessages;
    for i2 := 0 to WebBrowser1.OleObject.Document.frames.length-1 do
    begin
      for j := 0 to WebBrowser1.OleObject.Document.frames.item(i2).document.forms.Length-1 do  //Zugriff verweigert
      begin
        for j2:=0 to WebBrowser1.OleObject.Document.frames.item(i2).Document.forms.item(j).Elements.length-1 do
        begin
          if WebBrowser1.OleObject.Document.frames.item(i2).document.forms.Item(j).Elements.item(j2).Name = 'loginControl_txt_email' then
          begin
            WebBrowser1.OleObject.Document.frames.item(i2).document.forms.Item(j).Elements.item(j2).Value := Memo2.lines[i];
            showmessage('emok');
          end;
          if WebBrowser1.OleObject.Document.frames.item(i2).document.forms.Item(j).Elements.item(j2).Name = 'loginControl_txt_pwd' then
          begin
            WebBrowser1.OleObject.Document.frames.item(i2).document.forms.Item(j).Elements.item(j2).Value := Memo3.lines[i];
            showmessage('pwok');
          end;
          if (WebBrowser1.OleObject.Document.frames.item(i2).document.forms.Item(j).Elements.item(j2).Type = 'submit'and (WebBrowser1.OleObject.document.frames.Item(i2).document.forms.Item(j).Elements.item(j2).Id = 'loginControl_bt_continue'then
          begin
            WebBrowser1.OleObject.Document.frames.item(i2).document.forms.Item(j).Elements.item(j2).click;
            showmessage('btok');
          end;
        end;
      end;
    end;

hierbei krieg ich die exception 'Zugriff verweigert' :(

mfg


Lannes - Sa 27.06.09 23:03

Hallo,

vermute das der IFrame noch nicht vollständig geladen ist.
Die Überprüfung die Du mit WebBrowser1.ReadyState vornimmst ist kritisch beim Umgang mit Frames.
:arrow: besser in WebBrowser.OnDocumentComplete den Ladezustand prüfen.


the-kecks - So 28.06.09 00:35

hab das jetzt mal mit nem boolean wert gelöst:

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:
34:
35:
36:
37:
38:
39:
40:
41:
var
  Form1: TForm1;
  bLoaded : Boolean;
[...]
    Webbrowser1.Navigate('http://www.gamesload.de/de/mygamesload/kaufen.php?intIdGame=31044&partner=bbyd');
    while bLoaded=false do application.processmessages;
    for i2 := 0 to WebBrowser1.OleObject.Document.frames.length-1 do
    begin
      for j := 0 to WebBrowser1.OleObject.Document.frames.item(i2).document.forms.Length-1 do
      begin
        for j2:=0 to WebBrowser1.OleObject.Document.frames.item(i2).Document.forms.item(j).Elements.length-1 do
        begin
          if WebBrowser1.OleObject.Document.frames.item(i2).document.forms.Item(j).Elements.item(j2).Name = 'loginControl_txt_email' then
          begin
            WebBrowser1.OleObject.Document.frames.item(i2).document.forms.Item(j).Elements.item(j2).Value := Memo2.lines[i];
            showmessage('emok');
          end;
          if WebBrowser1.OleObject.Document.frames.item(i2).document.forms.Item(j).Elements.item(j2).Name = 'loginControl_txt_pwd' then
          begin
            WebBrowser1.OleObject.Document.frames.item(i2).document.forms.Item(j).Elements.item(j2).Value := Memo3.lines[i];
            showmessage('pwok');
          end;
          if (WebBrowser1.OleObject.Document.frames.item(i2).document.forms.Item(j).Elements.item(j2).Type = 'submit'and (WebBrowser1.OleObject.document.frames.Item(i2).document.forms.Item(j).Elements.item(j2).Id = 'loginControl_bt_continue'then
          begin
            WebBrowser1.OleObject.Document.frames.item(i2).document.forms.Item(j).Elements.item(j2).click;
            showmessage('btok');
          end;
        end;
      end;
    end;
[...]
procedure TForm1.WebBrowser1DocumentComplete(Sender: TObject;
  const pDisp: IDispatch; var URL: OleVariant);
begin
if pDisp = WebBrowser1.DefaultInterface then bLoaded:=true;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  bLoaded:=false;
end;

der zeigt mir aber leider immernoch den gleichen fehler.

mfg


jaenicke - So 28.06.09 00:38

Probiere es doch einfach einmal mit zwei Knöpfen...
Einen zum Laden und einen für den restlichen Code, der dann manuell gedrückt wird, wenn man sieht, dass alles fertig geladen ist. Wenn es dann klappt, dann weißt du, dass das Warten nicht richtig geklappt hat.


the-kecks - So 28.06.09 01:42

mit den buttons hab ichs 2x probiert...beide male bluescreen beim navigieren -.-
hab dann einfach ne wartezeit von 20 sek eingebaut, das dürfte ja reichen. immernoch zugriff verweigert

mfg


Delete - So 28.06.09 10:16

Versuch doch mal folgende Abfrage (statt "while bLoaded=false do..."):


Delphi-Quelltext
1:
if TWebbrowser.ReadyState <> READYSTATE_COMPLETE then...                    


jaenicke - So 28.06.09 10:21

Mit if? Wenn, dann mit while. Aber das wird auch nichts am Problem ändern, denn wenn es manuell mit separaten Buttons nicht klappt, liegt es daran auch nicht.

Ich kann da nur HttpFox [https://addons.mozilla.org/en-US/firefox/addon/6647], Firebug, Wireshark, Fiddler2, ... empfehlen um zu analysieren was da passiert beim Login und z.B. durch Anzeige der Postdaten des TWebBrowsers vor dem Abschicken zu vergleichen was da anders läuft.


the-kecks - So 28.06.09 13:27

hathor: hatte ich ja, aber mir wurde geraten es mal mit onDocumentComplete auszuprobieren, wegen den frames. Es geht aber leider immernoch nicht (zugriff verweigert) :(

mfg


the-kecks - So 28.06.09 20:18

jaenicke, ich hab jetzt live HTTP headers, ist das auch ok?
und die wie lasse ich mir die postdaten ausgeben? hab nur diesen [http://www.delphipraxis.net/topic104947.html] thread gefunden, weiß aber nicht ob das die daten sind, die ich benötige.

mfg


jaenicke - So 28.06.09 21:29

Ja, das sind die Daten, dort findest du ganz unten eine Funktion, die die Postdaten in einen String umwandelt, den kannst du dir einfach einmal ausgeben lassen und mit den richtigen vergleichen. (Das geht auch, wenn du im TWebBrowser die Daten manuell eingibst und schaust was dann anderes herauskommt.)


jaenicke - Mo 29.06.09 19:50

Ich habe gerade einmal das HTTP Header Plugin angeschaut, das ist wohl nicht das richtige.
Am einfachsten geht es wohl mit HttpFox [https://addons.mozilla.org/en-US/firefox/addon/6647], das ich eben auch oben ergänzt habe. Da hast du dann einfach nen Knopf in der Statusleiste auf den du klickst, dann werden die Postdaten direkt angezeigt.


the-kecks - Mi 01.07.09 15:03

ich habs gelassen mit dem TWebBrowser. Ich mach das jetzt mit IdHTTP

mfg