1. 程式人生 > >獲取iframe中的內容、查詢獲取指定元素(關於用c++呼叫WEBBROWSER控制元件,使用相關介面操作web頁面元素的一些方法)

獲取iframe中的內容、查詢獲取指定元素(關於用c++呼叫WEBBROWSER控制元件,使用相關介面操作web頁面元素的一些方法)

最近開發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;
}