3 Stimmen

Anwendung sperrt beim Versuch, auf TWebbrowsers HTML zuzugreifen

Editar Ich habe es auf diese 1 Zeile eingegrenzt,

HTML := wb.OleObject.Document.documentElement.innerHTML;

die Zeit verbraucht... wie kann das beschleunigt werden?

Mit dem folgenden Code kann meine Anwendung für 1-2 Sekunden hängen, während sie versucht, auf den HTML-Code einer Seite zuzugreifen (Delphi XE).

function Button1Click(Sender : TObject);
begin
   wb.navigate('http://10.0.0.154/stats');
   // Use a timer to poll the page - dont wait and process app messages
   timer1.enabled := true;
end;

procedure Timer1Timer(Sender : TObject);
var
  HTML : WideString;
begin
   If GetHTML(HTML) = true then
   begin
      Timer1.enabled := false;
      { do something }
   end;
end;

function GetHTML(var HTML : WideString) : boolean;
var
  Document : IHTMLDocument2;
begin
  HTML := '';
  Result := false;

  Document := wb.DOcument as IHTMLDocument2;
  If Assigned(Document) then
  begin
    try
      HTML := wb.OleObject.Document.documentElement.innerHTML;
      Result := true;
    except
      Result := false;
    end;
  end;
end;

Allerdings bemerke ich in meiner GetHTML-Methode kann 1-2 Sekunden dauern, um etwas zurückzugeben und es sperrt UI. Ein Blick auf die AQTime mit Delphi XE sagt, dass der Methodenaufruf langsam ist (1-2 Sekunden). Es ist sporadisch und ich frage mich, ob es fehlschlägt, wenn die Seite noch mitten im Laden ist.

Die Seite, die ich lade, ist eine Inhouse-Seite, voll von Javascript und 500k groß, ich kann nicht die OnDocumentComplete verwenden, weil es feuert, bevor die Seite sogar bereit ist, auch wenn ich eine Überprüfung der ReadyState es noch zu früh feuert.

Kann mir jemand sagen, ob es einen schnelleren Weg gibt, um auf das HTML von TWebbrowser zuzugreifen?

4voto

whosrdaddy Punkte 11560

Bitte denken Sie daran, dass OnDocumentComplete beim Navigieren auf einer Seite mehrere Male (Frames) ausgelöst werden kann.

Wie man OnDocumentComplete richtig implementiert:

procedure YourForm.OnDocumentComplete(
  Sender: TObject;
  const pDisp: IDispatch;
  var URL: OleVariant);
var
  currentBrowser: IWebBrowser;
  topBrowser: IWebBrowser;
  document: OleVariant;
  windowName: string;
begin
  currentBrowser := pDisp as IWebBrowser;
  topBrowser := (Sender as TWebBrowser).DefaultInterface;
  if currentBrowser = topBrowser then
    ShowMessage('Complete document was loaded')
  else
  begin
    document := currentBrowser.Document;
    windowName := document.ParentWindow.Name;
    ShowMessage(Format('Frame "%s" was loaded', [windowName]));
  end;
end;

Quelle:

http://www.cryer.co.uk/brian/delphi/twebbrowser/twebbrowser_events.htm#OnDocumentComplete

2voto

crefird Punkte 1560

Ihr Problem scheint zu sein, dass Sie TWebBrowser nicht erlauben, das Laden der Seite abzuschließen, bevor Sie versuchen, den HTML-Code abzurufen. Dies ist nur eine Vermutung, weil Sie nicht zeigen, wie der Code, wo Sie wb.Navigate aufrufen und Sie haben mit Ausnahmen erhalten die InnerHTML zu behandeln.

Sie sollten Folgendes versuchen:

procedure TForm1.GetHTML(URL: string; var HTML: string);
begin
  wb.Navigate(URL);
  Application.ProcessMessages;
  while wb.Busy do
    Application.ProcessMessages;
  HTML := wb.OleObject.Document.documentElement.innerHTML;
end;

0voto

LaKraven Punkte 5746

Wie bei der Antwort von @crefird vermute ich, dass Sie versuchen, auf das InnerHTML zuzugreifen, bevor der Browser seine Arbeit abgeschlossen hat...

Wenn ReadState/Busy keine genaue Darstellung des Belegungszustands des TWebBrowser liefern, können Sie dies tun:

1) Erstellen Sie entweder eine globale Variable oder ein privates Mitglied Ihres Formulars... wie "FBrowserBusy: Boolean" (VERGESSEN SIE NICHT, IHN VOR DEM AUFRUF von ".Navigate" auf TRUE zu INITIALISIEREN) 2) Wie @crefird in seiner Antwort gezeigt hat, verwenden Sie eine "while"-Schleife, nur ersetzen Sie "wb.Busy" für "FBrowserBusy". 3) Fügen Sie ein OnDocumentComplete-Ereignis zu Ihrer TWebBrowser-Instanz hinzu, und lassen Sie dieses FBusy := False setzen;

Dadurch werden Kollisionen vermieden und es wird sichergestellt, dass das TWebBrowser-Objekt das Laden des Dokuments abgeschlossen hat, bevor Ihre äußere Routine mit der Abfrage fortfährt.

Ich hoffe, Sie finden dies hilfreich!

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X