首页 > 解决方案 > 德尔福网页浏览

问题描述

我想自动化以下过程:我登录到一个网站。在搜索页面,输入我要搜索的信息,点击搜索按钮。点击加载我的结果。从结果页面中,我选择预览 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;

标签: delphitwebbrowser

解决方案


提交 web 表单是一种导航,因此您必须在调用后再次等待ReadyStateandBusy属性tibAutentification.click(假设这是 web 表单的提交按钮)。与第二次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;

推荐阅读