您的位置:首页 > 编程语言 > C语言/C++

获取iframe中的内容、查找获取指定元素(关于用c++调用WEBBROWSER控件,使用相关接口操作web页面元素的一些方法)

2017-10-13 10:35 2061 查看
最近开发WINDOWS下的应用程序,需要用到C++中调用WEBBROWSER控件操作网页的相关技术,查阅了一下相关文档,反复调试了几天,对其中的技术有了一些肤浅的认识,大多数C++程序员对COM应该不陌生,其实用C++操作网页,在前端应用层上主要就是对COM接口的查询与使用。以下是我写的一些代码与大家分享一下,总结一下几个关键点,

1、首先要找准元素的接口类型,html的标签(即元素类型,也许我的说法过于肤浅),有关元素类型的定义在mshtml.h头文件基本包括了所有接口类型,要是对web元素接口类型不太了解,可在网上查一下,有很多对定义有中文注释的资料;

2、要对com接口的查询(QueryInterface())格外注意,使用智能指针时的初始化声明,其实也是通过接口查询对指针进行的初始化赋值,接口的查询成败与否,直接关系到能否对网页元素进操作,所以至关重要;

 下面是一些代码和简单的注释,希望对需要的朋友们能有所帮助,

//根据类名查找网页元素

CComQIPtr<IHTMLElement> FindWebElement(CComQIPtr<IHTMLElementCollection> pEleColl,string strClassName)

{
CComQIPtr<IHTMLElement> spRetEle;
if(pEleColl == NULL)
{
//所给集合为空时,使用网页控件接口获取顶层页面的全部元素集合(这个是我程序类成员m_pWebBrowserEventHandler->m_pWebClientCall)
CComPtr<IWebBrowser2> pWeb2 = m_pWebBrowserEventHandler->m_pWebClientCall->GetWebBrowser2();
CComPtr<IDispatch> spDp =  NULL;
if(pWeb2)
{
HRESULT hr;
hr=pWeb2->get_Document(&spDp);
if(FAILED(hr))
return spRetEle;
}
else
return spRetEle;
CComQIPtr<IHTMLDocument2> pHtmlDoc2 = spDp;
pHtmlDoc2->get_all(&pEleColl);
}

long lCollCount = 0;
pEleColl->get_length(&lCollCount);
long lItem=0;
for(lItem=0; lItem<lCollCount; lItem++)
{
CComPtr<IDispatch> spDp;
HRESULT hr0 = pEleColl->item(CComVariant(lItem),CComVariant(),&spDp);
if( FAILED( hr0 ) ) continue;
CComQIPtr<IHTMLElement, &IID_IHTMLElement> spEleDp(spDp);  
if( spEleDp == NULL )continue;
CComBSTR sClassName;
HRESULT hr1 = spEleDp->get_className(&sClassName);
if( FAILED( hr1 ) ) continue;
if(sClassName.Length()==0) continue;
_bstr_t strTemp = sClassName.m_str;
char* pName = strTemp;
if(strClassName.compare(pName) == 0)
{
spRetEle = spEleDp;
break;
}
}
return spRetEle;

}

//遍历搜索子框架,获取所有子框架的HTML文档

vector<string> GetAllSubFrame(CComQIPtr<IHTMLDocument2> spDoc2)

{
string strVal="";
vector<string> sVec;
if(!spDoc2) return sVec;
CComPtr<IHTMLFramesCollection2>  spFramesColl;
spDoc2->get_frames(&spFramesColl);
long lCount=0,lItem=0;
CComBSTR sContext;
HRESULT hr = spFramesColl->get_length(&lCount);
if(FAILED(hr)) return sVec;
for(lItem=0; lItem<lCount; lItem++)
{
CComVariant sResultV;
CComVariant sIndex(lItem);
hr = spFramesColl->item(&sIndex,&sResultV);
if(FAILED(hr)) continue;
CComQIPtr<IHTMLWindow2> spWin = sResultV.pdispVal;
if(!spWin) continue;
CComPtr<IHTMLDocument2> spSubDoc;
hr = spWin->get_document(&spSubDoc);
if(FAILED(hr)) continue;
CComQIPtr<IHTMLElement> spBody;
hr = spSubDoc->get_body(&spBody);
if(FAILED(hr)) continue;
spBody->get_outerHTML(&sContext);
_bstr_t bstrStr = sContext.m_str;
char* str = bstrStr;
strVal = str?str:"";
sVec.push_back(strVal);
}
return sVec;

}

//遍历搜索子框架,获取指定ID或NAME的子框架的HTML文档(注意Name有时会有重复,所以ID更为精准些)

string GetSubFrame(CComQIPtr<IHTMLDocument3> spDoc3,string strID,string strName)

{
string strVal;
if(!spDoc3) strVal;
HRESULT hr;
CComBSTR sContext;
CComQIPtr<IHTMLElementCollection> spEleColl;
CComQIPtr<IHTMLElement> spEle, spBody;
CComPtr<IHTMLFrameBase2> spFB2;  
CComPtr<IHTMLWindow2> spWin; 
CComPtr<IHTMLDocument2> spSubDoc;
CComBSTR sParam = strID.c_str();
if(!strID.empty())
{
//获取指定ID的iframe中<BODY>标签中的内容
//获取元素对象接口
spDoc3->getElementById(sParam,&spEle);
//获取框架根元素对象接口
hr=spEle->QueryInterface(IID_IHTMLFrameBase2,(void**)&spFB2);  
if(FAILED(hr)) return strVal;
//获取HTML窗口对象接口
hr=spFB2->get_contentWindow(&spWin);
if(FAILED(hr)) return strVal;
//获取HTML文本对象接口
hr = spWin->get_document(&spSubDoc);
if(FAILED(hr)) return strVal;
//获取BODY元素对象接口
hr = spSubDoc->get_body(&spBody);
if(FAILED(hr)) return strVal;
spBody->get_outerHTML(&sContext);
}
else if(!strName.empty())
{
hr = spDoc3->getElementsByName(sParam,&spEleColl);
if(FAILED(hr)) return strVal;
long lCount=0;
hr = spEleColl->get_length(&lCount);
if(FAILED(hr)) return strVal;
CComPtr<IDispatch> spDp =  NULL;
for(long lItem=0; lItem<lCount; ++lItem)
{
//获取name集合中首个匹配的元素
hr = spEleColl->item(CComVariant(strName.c_str()),CComVariant(lItem),&spDp);
if(FAILED(hr)) continue;
break;
}
if(!spDp) return strVal;
//获取元素对象接口
hr = spDp->QueryInterface(IID_IHTMLElement,(void**)&spEle);
if(FAILED(hr)) return strVal;
//获取框架根元素对象接口
hr=spEle->QueryInterface(IID_IHTMLFrameBase2,(void**)&spFB2);  
if(FAILED(hr)) return strVal;
//获取HTML窗口对象接口
hr=spFB2->get_contentWindow(&spWin);
if(FAILED(hr)) return strVal;
//获取HTML文本对象接口
hr = spWin->get_document(&spSubDoc);
if(FAILED(hr)) return strVal;
//获取BODY元素对象接口
hr = spSubDoc->get_body(&spBody);
if(FAILED(hr)) return strVal;
spBody->get_outerHTML(&sContext);
}
if(sContext.Length()>0)
{
_bstr_t bstrStr = sContext.m_str;
char* str = bstrStr;
strVal = str?str:"";
}
return strVal;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐