请问高手怎样才能枚举出网页中所有“输入框”位置(包括IFRAME中),在线等

原创 2008年10月03日 11:19:00
 请问高手怎样才能枚举出网页中所有“输入框”位置(包括IFRAME中),在线等
楼主jinhe1314(hoyoo)2006-05-30 18:43:12 在 VC/MFC / HTML/XML 提问

我用www.codeproject.com上的一个例子,结合vckbase上扬老师的例子实现了这个要求,但是太慢了足足用了15-20秒。请高人指点 问题点数:100、回复次数:12Top

1 楼jiangsheng(蒋晟.Net[MVP])回复于 2006-05-31 01:55:11 得分 50

不要访问IHTMLElementCollection::get_length,用IHTMLElementCollection::get__newEnum  
  void   ListAllLinkUrls(mshtml::HTMLDocument   *myDoc)  
  {  
  mshtml::IHTMLElementCollection   *elementcollection   =  
  dynamic_cast<mshtml::IHTMLElementCollection*>(myDoc->all);  
  if   (elementcollection)   {  
  System::Collections::IEnumerator   *ienum   =  
  elementcollection->GetEnumerator();  
  while   (ienum   &&   ienum->MoveNext())   {  
  mshtml::IHTMLElement   *elem=dynamic_cast<mshtml::IHTMLElement  
  *>(ienum->Current);  
  if   (elem)   {  
  if   (elem->tagName->Equals(S"FRAME"))   {  
  mshtml::HTMLFrameBase   *fb   =   dynamic_cast<mshtml::HTMLFrameBase*>(elem);  
  mshtml::HTMLDocument  
  *myDoc2=dynamic_cast<mshtml::HTMLDocument*>(fb->document);  
  ListAllLinkUrls(myDoc2);  
  }  
  else   if   (elem->tagName->Equals(S"LINK"))   {  
  mshtml::HTMLLinkElement   *le   =  
  dynamic_cast<mshtml::HTMLLinkElement*>(elem);  
  Console::WriteLine("have   link   {0}",le->href);  
  }  
  }  
  }  
  }  
  }   //   ListAllLinkUrlsTop

2 楼lion_wing(凤之焚-业与情的纠缠,死而复生的蜕变!)回复于 2006-05-31 08:50:07 得分 0

自己写过一段,代码复杂,不如这个简单,MARK一下!Top

3 楼jinhe1314(hoyoo)回复于 2006-05-31 10:57:39 得分 0

to   jiangsheng  
  我用你的方法试了一下,分析www.5460.net用了将近6秒,  
  用pIHTMLDocument2->get_frames(   &spFramesCollection2   )和  
  pIHTMLDocument2->get_forms(   &spElementCollection   );  
  遍历用了不到1秒,但是用下面的代码得不出,正确的“IFRAME”中的“输入框”位置(需要吧IFRAME偏移加上才行)  
  pElem->get_offsetHeight(&Height);  
  pElem->get_offsetWidth(&Width);  
  pElem->get_offsetLeft(&Left);  
  pElem->get_offsetTop(&Top);  
  pElem->get_offsetParent(&lpContainer); while   (   lpContainer   )  
  {  
            lpContainer->get_offsetLeft(&lValue);   Left   +=   lValue;  
            lpContainer->get_offsetTop(&lValue);     Top   +=   lValue;  
            lpContainer->get_offsetParent(&lpContainer);  
  }  
  我想问的是怎样由“IHTMLWindow2”得到IFRAME偏移(就是转成IHTMLElement)  
  Top

4 楼lion_wing(凤之焚-业与情的纠缠,死而复生的蜕变!)回复于 2006-05-31 11:21:39 得分 0

用IHTMLFrameBase::get_marginWidth和IHTMLFrameBase::get_marginHeight  
  //mshtml::HTMLFrameBase   *fb   =   dynamic_cast<mshtml::HTMLFrameBase*>(elem);  
  fb->marginWidth(...);  
  fb->marginHeight(...);Top

5 楼jinhe1314(hoyoo)回复于 2006-05-31 11:26:18 得分 0

int   _tmain(int   argc,   TCHAR*   argv[],   TCHAR*   envp[])  
  {  
  ::CoInitialize(NULL); //初始化   COM   公寓  
   
  EnumIE(); //枚举浏览器  
   
  ::CoUninitialize(); //释放   COM   公寓  
   
  cout   <<   _T("======完成======")   <<   endl;  
  getchar(); //等待回车  
   
  return   0;  
  }  
   
  void   EnumIE(   void   )  
  {  
  cout   <<   _T("开始扫描系统中正在运行的浏览器实例")   <<   endl;  
   
  CComPtr<   IShellWindows   >   spShellWin;  
  HRESULT   hr   =   spShellWin.CoCreateInstance(   CLSID_ShellWindows   );  
  if   (   FAILED   (   hr   )   )  
  {  
  cout   <<   _T("获取   IShellWindows   接口错误")   <<   endl;  
  return;  
  }  
   
  long   nCount   =   0; //   取得浏览器实例个数(Explorer   和   IExplorer)  
  spShellWin->get_Count(   &nCount   );  
  if(   0   ==   nCount   )  
  {  
  cout   <<   _T("没有在运行着的浏览器")   <<   endl;  
  return;  
  }  
   
  for(int   i=0;   i<nCount;   i++)  
  {  
  CComPtr<   IDispatch   >   spDispIE;  
  hr=spShellWin->Item(CComVariant(   (long)i   ),   &spDispIE   );  
  if   (   FAILED   (   hr   )   ) continue;  
   
  CComQIPtr<   IWebBrowser2   >   spBrowser   =   spDispIE;  
  if   (   !spBrowser   ) continue;  
   
  CComPtr   <   IDispatch   >   spDispDoc;  
  hr   =   spBrowser->get_Document(   &spDispDoc   );  
  if   (   FAILED   (   hr   )   ) continue;  
   
  CComQIPtr<   IHTMLDocument2   >   spDocument2   =   spDispDoc;  
  if   (   !spDocument2   ) continue;  
   
  //   程序运行到此,已经找到了   IHTMLDocument2   的接口指针  
   
  //   删除下行语句的注释,把浏览器的背景改变看看  
  //   spDocument2->put_bgColor(   CComVariant(   "green"   )   );  
  DWORD   dwStart   =   GetTickCount();  
  EnumForm(   spDocument2   ); //枚举所有的表单  
  DWORD   dwEnd=GetTickCount()   ;  
  DWORD   x=dwEnd-dwStart;  
   
  }  
  }  
   
  void   EnumFrame(   IHTMLDocument2   *   pIHTMLDocument2   )  
  {  
  if   (   !pIHTMLDocument2   ) return;  
   
  HRESULT   hr;  
   
  CComPtr<   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;  
  CComQIPtr<   IHTMLWindow4   >   spWin4   =   vDispWin2.pdispVal;  
   
  if(   !spWin2   ) continue; //取得子框架的   IHTMLWindow2   接口  
  if(   !spWin4   ) continue;  
  CComQIPtr<   IHTMLFrameBase>   fbase;  
  hr=spWin4->get_frameElement(&fbase);//fbase永远是NULL  
   
  CComPtr   <   IHTMLDocument2   >   spDoc2;  
  spWin2->get_document(   &spDoc2   ); //取得字框架的   IHTMLDocument2   接口  
   
   
  EnumForm(   spDoc2   ); //递归枚举当前子框架   IHTMLDocument2   上的表单form  
  }  
  }  
   
  void   EnumForm(   IHTMLDocument2   *   pIHTMLDocument2   )  
  {  
  if(   !pIHTMLDocument2   ) return;  
   
  EnumFrame(   pIHTMLDocument2   ); //递归枚举当前   IHTMLDocument2   上的子框架fram  
   
  HRESULT   hr;  
  CComBSTR   bstrTitle;  
  pIHTMLDocument2->get_title(   &bstrTitle   ); //取得文档标题  
   
  USES_CONVERSION;  
  cout   <<   _T("====================")   <<   endl;  
  cout   <<   _T("开始枚举“")   <<   OLE2CT(   bstrTitle   )   <<   _T("”的表单")   <<   endl;  
  cout   <<   _T("====================")   <<   endl;  
   
  CComQIPtr<   IHTMLElementCollection   >   spElementCollection;  
  hr   =   pIHTMLDocument2->get_forms(   &spElementCollection   ); //取得表单集合  
  if   (   FAILED(   hr   )   )  
  {  
  cout   <<   _T("获取表单的集合   IHTMLElementCollection   错误")   <<   endl;  
  return;  
  }  
   
  long   nFormCount=0; //取得表单数目  
  hr   =   spElementCollection->get_length(   &nFormCount   );  
  if   (   FAILED(   hr   )   )  
  {  
  cout   <<   _T("获取表单数目错误")   <<   endl;  
  return;  
  }  
   
  for(long   i=0;   i<nFormCount;   i++)  
  {  
  IDispatch   *pDisp   =   NULL; //取得第   i   项表单  
  hr   =   spElementCollection->item(   CComVariant(   i   ),   CComVariant(),   &pDisp   );  
  if   (   FAILED(   hr   )   ) continue;  
   
  CComQIPtr<   IHTMLFormElement   >   spFormElement   =   pDisp;  
  pDisp->Release();  
   
  long   nElemCount=0; //取得表单中   域   的数目  
  hr   =   spFormElement->get_length(   &nElemCount   );  
  if   (   FAILED(   hr   )   ) continue;  
   
  for(long   j=0;   j<nElemCount;   j++)  
  {  
  CComDispatchDriver   spInputElement; //取得第   j   项表单域  
  hr   =   spFormElement->item(   CComVariant(   j   ),   CComVariant(),   &spInputElement   );  
  if   (   FAILED(   hr   )   ) continue;  
   
  CComVariant   vName,vVal,vType; //取得表单域的   名,值,类型  
  hr   =   spInputElement.GetPropertyByName(   L"name",   &vName   );  
  if(   FAILED(   hr   )   ) continue;  
  hr   =   spInputElement.GetPropertyByName(   L"value",   &vVal   );  
  if(   FAILED(   hr   )   ) continue;  
  hr   =   spInputElement.GetPropertyByName(   L"type",   &vType   );  
  if(   FAILED(   hr   )   ) continue;  
   
  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"); //未知类型  
   
  cout   <<   _T("[")   <<   lpType   <<   _T("]   ");  
  cout   <<   lpName   <<   _T("   =   ")   <<   lpVal   <<   endl;  
  }  
  //想提交这个表单吗?删除下面语句的注释吧  
  //pForm->submit();  
  }  
  }Top

6 楼jiangsheng(蒋晟.Net[MVP])回复于 2006-05-31 11:30:59 得分 0

Frame元素支持IWebBrowser2接口Top

7 楼jinhe1314(hoyoo)回复于 2006-05-31 11:31:23 得分 0

to   lion_wing  
  用蒋老大的方法枚举复杂的网页太慢了,用我上面的方法快,但是得不出IHTMLFrameBase接口他永远是NULLTop

8 楼jinhe1314(hoyoo)回复于 2006-05-31 11:37:22 得分 0

to   蒋老大  
  是的“Frame元素支持IWebBrowser2接口”但是得不出,正确的“Frame”中的“输入框”位(需要吧Frame偏移加上才行)  
  Top

9 楼lion_wing(凤之焚-业与情的纠缠,死而复生的蜕变!)回复于 2006-05-31 11:41:02 得分 50

CComPtr<IHTMLDocument3>   pDoc3;  
  hr   =   pDoc2->QueryInterface(IID_IHTMLDocument3,(void**)&pDoc3)   ;  
  if(hr==S_OK)  
  {  
  CComBSTR   bstrName("FRAME");  
  CComPtr<IHTMLElementCollection>   pElemCollFrame;  
  hr=pDoc3->getElementsByTagName(bstrName,&pElemCollFrame);  
  if   (hr==S_OK)  
  {  
  long   pLength;  
  hr=pElemCollFrame->get_length(&pLength);  
  if(hr==S_OK)  
  {  
  for(int   i=0;i<pLength;i++)  
  {  
  IDispatch   *pDispFrame=NULL;  
  CComVariant   vIndex=i;  
  hr=pElemCollFrame->item(vIndex,vIndex,&pDispFrame);  
  if(hr==S_OK)  
  {  
  CComPtr<IHTMLElement>   pElemFrame;  
  hr=pDispFrame->QueryInterface(IID_IHTMLElement,(void**)&pElemFrame);    
  if(hr==S_OK)  
  {  
  CComPtr<IHTMLFrameBase2>   pFrameBase2;  
  hr=pElemFrame->QueryInterface(IID_IHTMLFrameBase2,(void**)&pFrameBase2);  
  if(hr==S_OK)  
  {  
  CComPtr<IHTMLWindow2>   pWindow2;  
  hr=pFrameBase2->get_contentWindow(&pWindow2);  
  if(hr==S_OK)  
  {  
  CComPtr<IHTMLDocument2>   pDoc2Frame;  
  hr=pWindow2->get_document(&pDoc2Frame);  
  if   (hr==S_OK)  
  {  
  //得到IHTMLDocument2  
  }  
  }  
  }  
  }  
  }  
  pDispFrame->Release();  
  }  
  }  
  }  
  }  
  不好意思,代码没整理!Top

10 楼jinhe1314(hoyoo)回复于 2006-05-31 13:21:28 得分 0

感谢俩位老大,问题解决,应该给你两位每人100分,但是我只有100分只好每人50分,  
  再一次的感谢两位。Top

11 楼LVOLCANO(风起)回复于 2006-07-12 15:45:05 得分 0

MarkTop

12 楼whisperLin()回复于 2006-09-19 17:43:06 得分 0

mark

MFC编程实践--枚举某路径下的所有文件

MFC编程实例(1)――枚举文件夹下的所有文件。本例子实现的功能是枚举指定路径下的所有文件。程序最后的界面如下:程序中用到的控件有Group、Edit、Button、ListBox、static。我一...
  • FandLR
  • FandLR
  • 2005年05月16日 14:08
  • 3103

窗体句柄:枚举出当前系统所有窗体句柄

 窗体句柄:枚举出当前系统所有窗体句柄来源: 发布时间:星期三, 2008年10月29日 浏览:2次 评论:0有时玩需要一个软件在一定时间执行一件时情,而软件本身又不提供相关接口,更不用说可编程性了,...
  • bingwa
  • bingwa
  • 2008年11月01日 08:56
  • 390

框架Iframe指定网页位置嵌套代码

插入嵌入页的关键代码是 vspace=-200>   http://www.hao123.com是被嵌入的页面文件名,这个页可不能忘记上传,标签的作用相当于在网页的指定位置开了一个窗口,窗...
  • xb5186
  • xb5186
  • 2012年10月12日 16:35
  • 2162

按照字典序枚举排列

打印所有的排列        写了两个小程序,一个用于打印全排列,另一个用于打印可重复的排列。两个都是按字典序排列,用递归实现。后一个只是去掉了布尔型数组和相应的重复判断。 代码贴出来: /* ...
  • zhangxb35
  • zhangxb35
  • 2014年03月12日 20:31
  • 791

在IFRAME中编辑(HTML文本在线编辑器原理之一)

editarea.document.designMode="on";function a(){ alert(editarea.document.body.innerHTML);} 
  • banmuhuangci
  • banmuhuangci
  • 2006年09月27日 23:07
  • 1914

iframe 完美嵌入网页

控制边框等,直接上代码 function showS() { document.getElementById("test").scrolling="yes"; docu...
  • DeathMemory
  • DeathMemory
  • 2016年11月18日 12:39
  • 3798

MFC枚举窗口

bool C枚举窗口Dlg::EnumWindowsProc(HWND hWnd, LPARAM lParam) { if(::GetWindowLong(hWnd,GWL_STYLE)& WS_V...
  • ts1011
  • ts1011
  • 2013年05月24日 10:32
  • 767

枚举出当前系统所有窗体句柄

有时玩需要一个软件在一定时间执行一件时情,而软件本身又不提供相关接口,更不用说可编程性了,没办法,只能写个程序来自动控制它。首先第一步,找出相关程序的句柄,在此列出枚举出系统句柄的程序:#includ...
  • colijian
  • colijian
  • 2008年10月23日 11:31
  • 578

用iframe实现的网页局部刷新

    网上经常有人想要实现不刷新从服务器取数据的需求。本人理解就是局部刷新或者是隐藏刷新。有点象“偷偷摸摸”地从服务器拿数据而不让用户发觉的意思。本人想要实现局部刷新的思路是出于以下考虑的:    ...
  • cuckoo1
  • cuckoo1
  • 2007年09月12日 15:59
  • 7996

ionic ios iframe 白屏

问题:在ios下边使用iframe出现白屏问题android下边正常 原因是ios对app打开外部网页有限制需要取消限制 解决方法1. 确认添加whitelist 插件2.在config.xml中添加...
  • blackof2012
  • blackof2012
  • 2017年03月01日 16:28
  • 660
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:请问高手怎样才能枚举出网页中所有“输入框”位置(包括IFRAME中),在线等
举报原因:
原因补充:

(最多只允许输入30个字)