Delphi WebBrowsing - PullRequest
       43

Delphi WebBrowsing

0 голосов
/ 11 апреля 2020

Я хочу автоматизировать следующий процесс: я захожу на сайт. На странице поиска введите информацию, которую я хочу найти, и нажмите кнопку поиска. Клик загружает мой результат. На полученной странице я выбираю опцию предварительного просмотра PDF-файла и нажимаю кнопку. Этот щелчок загружает мой файл PDF.

Если я разделил эти команды на кнопки и нажал по одной, все работает нормально, но когда я хочу выполнить все команды подряд, я получаю сообщение об ошибке , (Я думаю, что ошибка в том, что WebBrowser загружает не все.) Пожалуйста, помогите.

procedure TMainForm.Button10Click(Sender: TObject);
var doc :IHTMLDocument2;
    FileStream: TFileStream;
    StreamAdapter: IStream;
    PersistStreamInit: IPersistStreamInit;
    i, a, b : integer;
    sir: string;
    MergiInainte:boolean;'

begin
    MergiInainte:=false;
    WebBrowser1.Navigate('https://website/externallogin.aspx');'

    repeat
      if ((WebBrowser1.ReadyState = READYSTATE_COMPLETE) and (WebBrowser1.Busy = false)) then
        MergiInainte:=true;
    until MergiInainte;'   // This repeat is not working. Dont know why?

    //After webBrowser is fully loaded, the next code has to be run
    doc := WebBrowser1.Document AS IHTMLDocument2;
    WebFormSetFieldValue(doc,0,'txtNume','user');
    WebFormSetFieldValue(doc,0,'txtPwd','psswd');
    WebBrowser1.OleObject.Document.GetElementByID('tibAutentification').click;'

    //after the above code is fully executat, next code is in line
    WebBrowser1.Navigate('https://website/Pages/SearchTitle.aspx');

    //after the above code is executed, next i need to complete form element with what the nexd data
    doc := WebBrowser1.Document AS IHTMLDocument2;
    WebBrowser1.OleObject.Document.GetElementByID('chkTitleNo').click;
    WebFormSetFieldValue(doc,0,'txtTitleNo','28972');   //nr titlu de proprietate
    WebBrowser1.OleObject.Document.GetElementByID('tibSearch').click;

    WebBrowser1.OleObject.Document.GetElementByID('fdgMain:_ctl3:imbView').click;

    WebBrowser1.OleObject.Document.GetElementByID('tibViewPDF').click;  
end;


// But i'm getting error:  Access violation....read of adress 0000000.'

procedure TForm1.WebFormSetFieldValue(const document: IHTMLDocument2; const formNumber: integer; const fieldName, newValue: string) ;
var form : IHTMLFormElement;
    field: IHTMLElement;
begin
  form := WebFormGet(formNumber, WebBrowser1.Document AS IHTMLDocument2) ;
  field := form.Item(fieldName,'') as IHTMLElement;
  if field = nil then Exit;
  if field.tagName = 'INPUT' then (field as IHTMLInputElement).value := newValue;
  if field.tagName = 'SELECT' then (field as IHTMLSelectElement).value := newValue;
  if field.tagName = 'TEXTAREA' then (field as IHTMLTextAreaElement).value := newValue;
end;

1 Ответ

2 голосов
/ 11 апреля 2020

Отправка веб-формы - это навигация, поэтому вам нужно снова подождать свойства ReadyState и Busy после вызова tibAutentification.click (при условии, что это кнопка отправки веб-формы). То же самое со вторым Navigate() вызовом. Кроме того, вам нужно прокачать очередь сообщений вызывающего потока в ожидании готовности браузера, чтобы он действительно мог корректно обрабатывать изменения своего состояния.

procedure TMainForm.Button10Click(Sender: TObject);
var
  doc: IHTMLDocument2;
  doc3: IHTMLDocument3;
  FileStream: TFileStream;
  StreamAdapter: IStream;
  PersistStreamInit: IPersistStreamInit;
  i, a, b : integer;
  sir: string;

  procedure WaitForReady;
  begin
    while WebBrowser1.ReadyState <> READYSTATE_COMPLETE do
      Application.ProcessMessages;
  end;

begin
  WebBrowser1.Navigate('https://website/externallogin.aspx');

  WaitForReady;
  doc := WebBrowser1.Document as IHTMLDocument2;
  doc3 := doc as IHTMLDocument3;
  WebFormSetFieldValue(doc,0,'txtNume','user');
  WebFormSetFieldValue(doc,0,'txtPwd','psswd');
  doc3.GetElementByID('tibAutentification').click;

  WaitForReady;
  WebBrowser1.Navigate('https://website/Pages/SearchTitle.aspx');

  WaitForReady;
  doc := WebBrowser1.Document as IHTMLDocument2;
  doc3 := doc as IHTMLDocument3;
  doc3.GetElementByID('chkTitleNo').click;
  WebFormSetFieldValue(doc,0,'txtTitleNo','28972');   //nr titlu de proprietate
  doc3.GetElementByID('tibSearch').click;

  WaitForReady; // ?
  doc := WebBrowser1.Document as IHTMLDocument2;
  doc3 := doc as IHTMLDocument3;
  doc3.GetElementByID('fdgMain:_ctl3:imbView').click;

  WaitForReady; // ?
  doc := WebBrowser1.Document as IHTMLDocument2;
  doc3 := doc as IHTMLDocument3;
  doc3.GetElementByID('tibViewPDF').click;  
end;

procedure TForm1.WebFormSetFieldValue(const document: IHTMLDocument2;
  const formNumber: integer; const fieldName, newValue: string);
var
  form : IHTMLFormElement;
  field: IHTMLElement;
begin
  if document = nil then Exit;
  form := WebFormGet(formNumber, document);
  if form = nil then Exit;
  field := form.Item(fieldName,'') as IHTMLElement;
  if field = nil then Exit;
  if field.tagName = 'INPUT' then
    (field as IHTMLInputElement).value := newValue
  else if field.tagName = 'SELECT' then
    (field as IHTMLSelectElement).value := newValue
  else if field.tagName = 'TEXTAREA' then
    (field as IHTMLTextAreaElement).value := newValue;
end;

Из-за проблем с повторным входом, связанных с ручной перекачкой очереди сообщений, сериализация этого кода не является хорошей идеей, вместо этого следует использовать событие браузера OnDocumentComplete, разрешив VCL обрабатывать обработку сообщений для вас. Например, (может потребоваться некоторая настройка):

procedure TMainForm.Button10Click(Sender: TObject);
begin
  WebBrowser1.Navigate('https://website/externallogin.aspx');
  WebBrowser1.Tag := 1;
end;

procedure TMainForm.WebBrowser1DocumentComplete(ASender: TObject;
  const Disp: IDispatch; const URL: OleVariant);
var
  doc: IHTMLDocument2;
  doc3: IHTMLDocument3;
begin
  case WebBrowser1.Tag of
    1: begin
      doc := WebBrowser1.Document as IHTMLDocument2;
      doc3 := doc as IHTMLDocument3;
      WebFormSetFieldValue(doc,0,'txtNume','user');
      WebFormSetFieldValue(doc,0,'txtPwd','psswd');
      doc3.GetElementByID('tibAutentification').click;
      WebBrowser1.Tag := 2;
    end;

    2: begin
      WebBrowser1.Navigate('https://website/Pages/SearchTitle.aspx');
      WebBrowser1.Tag := 3;
    end;

    3: begin
      doc := WebBrowser1.Document as IHTMLDocument2;
      doc3 := doc as IHTMLDocument3;
      doc3.GetElementByID('chkTitleNo').click;
      WebFormSetFieldValue(doc,0,'txtTitleNo','28972');   //nr titlu de proprietate
      doc3.GetElementByID('tibSearch').click;
      WebBrowser1.Tag := 4;
    end;

    4: begin
      doc := WebBrowser1.Document as IHTMLDocument2;
      doc3 := doc as IHTMLDocument3;
      doc3.GetElementByID('fdgMain:_ctl3:imbView').click;
      WebBrowser1.Tag := 5;
    end;

    5: begin
      doc := WebBrowser1.Document as IHTMLDocument2;
      doc3 := doc as IHTMLDocument3;
      doc3.GetElementByID('tibViewPDF').click;
      WebBrowser1.Tag := 0;
    end;
  end;
end;
...