zoukankan      html  css  js  c++  java
  • 网站复杂信息自动录入处理

    问题:某某系统是基于B/S的,无法获得数据接口,有信息录入页面,该信息录入页面是基于showModalDialog的,且录入完初步信息后会redirect到另一URL(假设原URL为URL1,重定向后URL为URL2),其他的信息在URL2中要通过javascript切换链接(像TAB页效果一样)才能继续录入,录入过程中有可能提交后有alert信息提示,现有待数据一堆(1000条),要求实现数据的程序自动化录入。

    解决方案:使用ExtendedWebBrowser处理,用WebBrowser打开URL1,取得HTML文档后自动填写表单,然后调用提交函数,待转向URL2后,再调用Javascript函数转向其他信息录入页面,并自动填写表单,调用保存JS函数,一条记录的所有信息录入完成后,转向URL1,重新开始,录入下一条数据。

    几个技术点:
    1.目标系统中showModalDialog出来的页面无状态条,无法知道URL1。
    解决:先通过ieHttpHeaders跟踪showModalDialog,取得URL1的实际值。

    2.无法得知录入页面是否加载完成。
    解决:在DocumentCompleted事件处理程序中判断ReadyState后,加入输出e.url语句,启动自已基于ExtendedWebBrowser开发的浏览器程序,把各步骤中表单可以自动填单后的最后输出的那个URL记录下来,形成各步骤的特征URL,这样就能处理frames和Iframe及JS中加载的页面。如:
    void brw_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
          {
              if (_windowManager.ActiveBrowser.ReadyState == WebBrowserReadyState.Complete)
              {
                  SouthHIS.modOutputLog.OutputLog(e.Url.ToString());
               }
            }
    记录下来的有:
    步骤1:http://xxx.xxx/BasicInfo.aspx?OpFlag=add&strGuardNo=
    步骤2:http://xxx.xxx/aaedit2.aspx
    步骤2:http://xxx.xxx/aaedit3.aspx

    3.各步骤填写表单有可能出错而要重复执行,如何让各步骤确定地执行完成上一步后再执行下一步并串起来.
    解决:使用状态机方案,画好状态机图,然后定义一个变量表示状态机状态,执行成功一个步骤后,改变状态变量以让状态机执行下一动作,如果执行不成功,可以返回重新执行,或是返回上一步再重新加载等。

    4.程序执行速度过快,即使程序表明页面载完成,自动填入表单时还是会发生一些页面里的onload时执行的未完成,导致后续填写表单或执行JS出错.即:判断出某步骤“加载完”最后的页面URL,执行填单程序,有时还是会出错,如何处理。
    解决:使用多线程,让步骤执行在非主线程上执行,在满足载条件后再等待一段时间,让WebBrowser加载彻底完成后,再使用invoke来执行各步骤的填单程序.
    样例程序:
     public    class InvokeObject
          {
              public System.Threading.ThreadStart m_func;
              public MainForm m_frm;
              public  InvokeAA(System.Threading.ThreadStart func,MainForm frm)
              {
                  m_func = func;
                  m_frm = frm;
              }
              public void ToThreadCall()
              {
                  DateTime dt1 = DateTime.Now;
                  while (true)//等待“加载完成”后再等待200MS
                  {
                      Application.DoEvents();
                      DateTime dt2 = DateTime.Now;
                      TimeSpan ts = dt2.Subtract(dt1);
                      if (ts.Milliseconds > 200)
                      {
                          break;
                      }
                  }
                  m_frm.Invoke(m_func);//执行真正的步骤处理函
              }
          }

    使用代码:
              InvokeAA abc = new InvokeAA(GoToFamilyPage, this);//GoToFamilyPage是步骤处理函数
              System.Threading.Thread th2 = new System.Threading.Thread(abc.ToThreadCall);
              th2.Name = "GoToFamilyPage";
              th2.Start();

    5.如何拦截alert对话框,以让其继续.
    解决:扩展WebBrowser,处理  ShowMessage.在extendedWebBrowser中,加入代码:
    //拦截alert
        #region ExtendedWebBrowserSite
        class ExtendedWebBrowserSite : WebBrowser.WebBrowserSite, UnsafeNativeMethods.IDocHostShowUI
        {
            WebBrowser m_host;
            public ExtendedWebBrowserSite(WebBrowser host)
                : base(host)
            {
                m_host = host;
            }
            void UnsafeNativeMethods.IDocHostShowUI.ShowMessage(ref UnsafeNativeMethods._RemotableHandle hwnd, string lpstrText, string lpstrCaption, uint dwType, string lpstrHelpFile, uint dwHelpContext, out int plResult)
            {
                //TODO:自定义处理弹出消息框
                //dwType:0x00000030问题
                SouthHIS.modOutputLog.OutputLog(lpstrText);
                SouthHIS.modOutputLog.OutputLog(dwType);
                if (dwType != 0x00000030)
                {

                    //plResult = (int)System.Windows.Forms.MessageBox.Show(lpstrText, lpstrCaption, (MessageBoxButtons)dwType );
                }
                plResult = 1;
            }
            void UnsafeNativeMethods.IDocHostShowUI.ShowHelp(ref UnsafeNativeMethods._RemotableHandle hwnd, string pszHelpFile, uint uCommand, uint dwData, UnsafeNativeMethods.tagPOINT ptMouse, object pDispatchObjectHit)
            {
                //TODO:自定义处理弹出帮助消息框
            }
        }

          protected override WebBrowserSiteBase CreateWebBrowserSiteBase()
          {
              return new ExtendedWebBrowserSite(this);
          }

    6.如何拦截执行JS出错时弹出的脚本错误对话框
    解决:在加载页面前,使用:
     brw.ScriptErrorsSuppressed = true;
    让其不显示对话框.

    7.如何取得frames,如何执行javascript,如何定义额外的javascript函数,如何取得执行javascript函数的返回值。
    解决:
              HtmlWindow win1 = _windowManager.ActiveBrowser.Document.Window.Frames[0];
              mshtml.IHTMLWindow2 win2 = (mshtml.IHTMLWindow2)win1.DomWindow;         
              try
              {
                 string script11 = "function SaveRow11() { return '0';}";
                 win2.execScript(script11, "javascript");
                 string strRetVal = (string)win1.Document.InvokeScript("SaveRow11");
                 if(strRetVal =='0')
                 {
                    ....
                  }
               }catch .....
              




  • 相关阅读:
    C#使用xpath简单爬取网站的内容
    Python的安装以及编译器的安装
    解析二维码
    C#的历史及IDE总结
    我又回来了,这回是带着C++来的
    Python 基础知识
    template declarations(模板声明)中 class 和 typename 有什么不同?
    投影点坐标
    内存对齐代码解析
    互斥量和信号量的区别
  • 原文地址:https://www.cnblogs.com/Render/p/1352705.html
Copyright © 2011-2022 走看看