Приложение блокируется при попытке доступа к TWebbrowsers HTML - PullRequest
3 голосов
/ 09 мая 2011

Редактировать Сузили до этой 1 строки,

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

который тратит время ... как это можно ускорить?

Используя следующий код, мое приложение может зависнуть на 1-2 секунды, пока оно пытается получить доступ к HTML-странице (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;

Однако я заметил, что в моем методе GetHTML может потребоваться 1-2 секунды, чтобы вернуть что-то, и это блокирует пользовательский интерфейс. Глядя на AQTime с Delphi XE, он говорит, что вызов метода медленный (1-2 секунды). Это споратично, и мне интересно, если это не удается, когда страница все еще находится в середине загрузки.

Страница, которую я загружаю, является внутренней страницей, полной javascript и размером 500 КБ, я не могу использовать OnDocumentComplete, потому что она срабатывает еще до того, как страница готова, даже если я проверяю ReadyState, он все еще срабатывает рано.

Кто-нибудь может пролить свет на то, если их более быстрым способом я смогу получить доступ к HTML из TWebbrowser?

Ответы [ 3 ]

4 голосов
/ 23 июня 2011

Пожалуйста, помните, что OnDocumentComplete может срабатывать несколько раз (кадров) при навигации по странице.

Как правильно реализовать OnDocumentComplete:

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;

Источник:

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

2 голосов
/ 09 мая 2011

Ваша проблема в том, что вы не позволяете TWebBrowser завершить загрузку страницы, прежде чем пытаться получить HTML.Это только предположение, потому что вы не показываете, как код, где вы вызываете wb.Navigate, и вам приходится иметь дело с исключениями, получающими InnerHTML.

Вы должны попробовать следующее:

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;
0 голосов
/ 12 мая 2011

Как и в случае ответа @ crefird, я подозреваю, что вы пытаетесь получить доступ к InnerHTML до того, как браузер завершит свою работу ...

Если ReadState / Busy не возвращают точные представления о состоянии занятости TWebBrowser, вы можете сделать это:

1) Создайте либо глобальную переменную, либо закрытый член вашей формы ... такой как "FBrowserBusy: Boolean" (НЕ ЗАБЫВАЙТЕ ИНИЦИАЛИЗОВАТЬ ЕГО ИСТИНА, ТОЛЬКО ДО ВЫЗОВА ".Navigate") 2) Как продемонстрировал @crefird в своем ответе, используйте цикл while, заменяя только «wb.Busy» на «FBrowserBusy». 3) Добавьте событие OnDocumentComplete к вашему экземпляру TWebBrowser, и установите это значение FBusy: = False;

Это исключит любое столкновение и гарантирует, что объект TWebBrowser завершил загрузку документа до того, как ваша внешняя подпрограмма продолжит его опрос.

Надеюсь, вы найдете это полезным!

...