关于自动填写表单的操作

来源:互联网 发布:linux open函数 编辑:程序博客网 时间:2024/04/27 20:44

如题,贴源码

void enumIE::newEnumForm(CString formName, CString httpValue, IHTMLDocument2 *pIHTMLDocument2) //表单操作
{

 if (pIHTMLDocument2==NULL)
 {
  return ;
 }
 // MessageBox(NULL,"111","",MB_OK);
 
 newEnumFrame(formName,httpValue,pIHTMLDocument2);   //递归枚举当前IHTMLDocument2上的子框架frame  
 
 HRESULT hr;
 
 USES_CONVERSION;      
 
 CComQIPtr<IHTMLElementCollection> spElementCollection;  
 
 hr=pIHTMLDocument2->get_forms(&spElementCollection); //取得表单集合  
 if (FAILED(hr))  
 {  
  FILLFORM_ERROR=F_GETFORMS_ERROR;
  return ;
 }  
 CComQIPtr <IDispatch> spDisp;
 CComQIPtr<IHTMLFormElement> pFormElement;
 hr=spElementCollection->item(CComVariant(formName),CComVariant("0"),&spDisp);//获得表单接口
 if(SUCCEEDED(hr))
 {
  
  pFormElement=spDisp;
  /////*******************************?处理字符串提交begin
  int num1=0;
  CString httpParaValue=httpValue;
  CString strbuf;
  int num2=0;
  FormValue httpparaBuf;
  CString strResult;
  for(int i=0;i<httpParaValue.GetLength();i++)
  {
   if(httpParaValue.GetAt(i)=='&')
   {  
    strbuf=httpParaValue.Mid(num1,i-num1);
    httpparaBuf=FormValue(strbuf);
    addValue(httpparaBuf.paraFo,httpparaBuf.paraBe,pFormElement);//填写数据
    num1=i+1;
    num2++;
    
   }
   
   
   if(i==(httpParaValue.GetLength()-1))
   {
    
    strbuf=httpParaValue.Mid(num1,i+1);
    httpparaBuf=FormValue(strbuf);
    addValue(httpparaBuf.paraFo,httpparaBuf.paraBe,pFormElement);//填写数据
    
   }
   
  }
  
  /////*******************************?处理字符串提交end
  FILLFORM_ERROR=F_SUCCEED;
  return ;
  
 }
 else
 {
  FILLFORM_ERROR=F_GETFORM_ERROR;
  return ;
 }
 
}

void enumIE::newEnumFrame(CString formName, CString httpValue, IHTMLDocument2 *pIHTMLDocument2)
{
 if (!pIHTMLDocument2)
 {
  return ;      
 }
 HRESULT   hr;  
   
 CComQIPtr<IHTMLFramesCollection2> spFramesCollection2;  
 pIHTMLDocument2->get_frames(&spFramesCollection2); //取得框架frame的集合  
   
 long nFrameCount=0;        //取得子框架个数  
 
 hr=spFramesCollection2->get_length(&nFrameCount); 
  
 if (FAILED(hr)|| 0==nFrameCount) return ;  
    
 for(long i=0; i<nFrameCount; i++)  
 {  
  CComVariant vDispWin2; //取得子框架的自动化接口  
  hr = spFramesCollection2->item(&CComVariant(i), &vDispWin2);  
  if (FAILED(hr)) continue;      
  CComQIPtr<IHTMLWindow2>spWin2 = vDispWin2.pdispVal;  
  if (!spWin2) continue; //取得子框架的   IHTMLWindow2   接口      
  CComQIPtr <IHTMLDocument2> spDoc2;  
  
  spDoc2=HtmlWindowToHtmlDocument(spWin2);
  // spWin2->get_document(&spDoc2); //取得子框架的   IHTMLDocument2   接口
  
  newEnumForm(formName,httpValue,spDoc2);      //递归枚举当前子框架   IHTMLDocument2   上的表单form  
  
  char buf[3];
  itoa(i,buf,10);
  //MessageBox(NULL,buf,"",MB_OK);
  
 }
}
CComQIPtr<IHTMLDocument2> enumIE::HtmlWindowToHtmlDocument(IHTMLWindow2* spWindow) //这个函数还有下面的那个是绕过跨域访问,虽然绕过跨域但是IE8 上不调整自动代理的问题就会出现登陆成功但是cookie丢失现象
{
 ATLASSERT(spWindow != NULL);
 
 CComQIPtr<IHTMLDocument2> spDocument;
 HRESULT hRes = spWindow->get_document(&spDocument);
   
 if ((S_OK == hRes) && (spDocument != NULL))
 {
  // The html document was properly retrieved.
  return spDocument;
 }
 
 // hRes could be E_ACCESSDENIED that means a security restriction that
 // prevents scripting across frames that loads documents from different internet domains.
    CComQIPtr<IWebBrowser2>  spBrws= HtmlWindowToHtmlWebBrowser(spWindow);
 if (spBrws == NULL)
 {
  return CComQIPtr<IHTMLDocument2>();
 }
 
 // Get the document object from the IWebBrowser2 object.
 CComQIPtr<IDispatch> spDisp;
 hRes = spBrws->get_Document(&spDisp);
 spDocument = spDisp;
 
 return spDocument;
}
CComQIPtr<IWebBrowser2> enumIE::HtmlWindowToHtmlWebBrowser(IHTMLWindow2* spWindow)
{
 ATLASSERT(spWindow != NULL);
 
 CComQIPtr<IServiceProvider>  spServiceProvider = spWindow;
 if (spServiceProvider == NULL)
 {
  return CComQIPtr<IWebBrowser2>();
 }
 
 CComQIPtr<IWebBrowser2> spWebBrws;
 HRESULT hRes = spServiceProvider->QueryService(IID_IWebBrowserApp, IID_IWebBrowser2, (void**)&spWebBrws);
 if (hRes != S_OK)
 {
  return CComQIPtr<IWebBrowser2>();
 }
 
 return spWebBrws;
}

 

 

void enumIE::addValue(CString putName,CString putValue,IHTMLFormElement * pIHTMLFormElement)
{
 if(pIHTMLFormElement==NULL)
 {
   return;
 }
 CString strResult;
 try{ 
  HRESULT hr;
  USES_CONVERSION;
  CComDispatchDriver spInputElement;
  
  
  CComPtr <IDispatch> pDisp;
  CComQIPtr<IHTMLElement, &IID_IHTMLElement> pElement;
 
  hr=pIHTMLFormElement->item(CComVariant(putName), CComVariant(long(0)), &spInputElement);
  if(FAILED(hr))
  {
   FILLFORM_ERROR=F_GETF_ELEMENT_ERROR;
   
  }

  hr=pIHTMLFormElement->item(CComVariant(putName), CComVariant(long(0)), &pDisp); 
  if(FAILED(hr))
  {
   FILLFORM_ERROR=F_GETF_ELEMENT_ERROR;
  }

  if(!FAILED(hr))
  { 
  
   pElement=pDisp;
   
   CComVariant vName,vVal,vType;     //取得表单域的名称,数值,类型
   spInputElement.GetPropertyByName(L"name", &vName);  
   spInputElement.GetPropertyByName(L"value", &vVal);  
   spInputElement.GetPropertyByName(L"type", &vType);  
   
   LPCTSTR lpName= vName.bstrVal ? OLE2CT(vName.bstrVal) : _T("NULL"); //未知域名  
   LPCTSTR lpVal=  vVal.bstrVal  ? OLE2CT(vVal.bstrVal)  : _T("NULL"); //空值,未输入  
   LPCTSTR lpType= vType.bstrVal ? OLE2CT(vType.bstrVal) : _T("NULL"); //未知类型 

   CString strType=lpType;
   if((strType=="radio")||(strType=="checkbox"))  //填表针对radio等东东,可以找到其数量然后循环即可,偷懒就直接让他跑循环
   {
    // MessageBox(NULL,"","",MB_OK);
    // pElement->click();
    int i=0;
    
    while(i<10)
    {
     hr=pIHTMLFormElement->item(CComVariant(putName), CComVariant(long(i)), &spInputElement);
     if(FAILED(hr))
        continue;
     
     hr=pIHTMLFormElement->item(CComVariant(putName), CComVariant(long(i)), &pDisp); 
     if(FAILED(hr))
      continue;
     pElement=pDisp;
     spInputElement.GetPropertyByName(L"value", &vVal);  
     LPCTSTR lpVal=  vVal.bstrVal  ? OLE2CT(vVal.bstrVal)  : _T("NULL"); //空值,未输入
     CString valueBuf=lpVal;
     if(lpVal==putValue)
     {
      pElement->click();
      CComVariant vSetStatus(L"checked");
      spInputElement.PutPropertyByName(L"checked",&vSetStatus); 
      FILLFORM_ERROR=F_SUCCEED;
      return;
     }
     i++;
    }
    FILLFORM_ERROR=F_FILLRADIO_ERROR;
    
    
   }
   else
   {
    CComVariant vSetStatus(putValue);
    spInputElement.PutPropertyByName(L"value",&vSetStatus); 
    FILLFORM_ERROR=F_SUCCEED;
    //  strResult="00操作成功";
   }
   // 
   
  }
  
 }
 catch(...)
 {
  FILLFORM_ERROR=F_EXCEPTION;///////////
  // strResult="07网页标签出错或其它异常,请检查";
 }
}
主要代码在上面,不多解释了

原创粉丝点击