以下使用的是www.csdn.net/expert的网页.
void CLeftView::GetAllRoom(IHTMLDocument2Ptr pDoc)
{
USES_CONVERSION;
IDispatchPtr pDisp;
IHTMLElementCollectionPtr pItems;
_variant_t vIndex, vDummy;
HRESULT hr;
long p(0);
pDoc->get_all(&pItems);
pItems->get_length(&p);
vIndex.vt = VT_I4;
try
{
hr = pDoc->get_all(&pItems);
if (FAILED(hr))
return;
pItems->get_length(&p);
long i(0);
for (; i < p; ++i)
{
vIndex.lVal = i;
IDispatchPtr pDisp;
if (SUCCEEDED(pItems->item(vIndex, vDummy, &pDisp)))
{
IHTMLLinkElementPtr pLink;
_bstr_t link;
if (SUCCEEDED(pDisp->QueryInterface(&pLink)))
{
TRACE("Get a link element/n"); // 只输出一次,不会只有一个吧???
if (SUCCEEDED(pLink->get_href((BSTR*)&link)))
{
;
}
}
}
}
}
catch (_com_error &e)
{
CString error = W2T(e.Description());
TRACE("exception : %s/n", error);
}
catch (...)
{
TRACE("Get Exception : unknow excpetion/n");
}
//-------
// Log it
//-------
CFile file;
int _count(0);
file.Open("c://test.txt", CFile::modeCreate | CFile::modeReadWrite);
for (_count = 0; _count < m_strRoom.GetSize(); ++_count)
{
file.Write(m_strRoom[_count], m_strRoom[_count].GetLength());
file.Write("/r/n", 4);
}
file.Close();
}
问题点数:120、回复次数:15Top
为什么我的总是没有人回答,Top
gzTop
这个是用的IE的内核吗?我对VC不懂,见笑了。Top
。原来兄台是位牛兄。失敬。。。失敬。Top
你想要得到什么?网页上的所有链接吗?Top
yeah.Top
我头发都 快白了。Top
why don't you use IHTMLDocument2::get_anchors Method
to retrieve an interface pointer to a zero-based collection of all the A objects in an HTML document.Top
let's try.Top
if (SUCCEEDED(pDoc->get_anchors(&pItems)))
{
pItems->get_length(&p); // p == 0 ???
....
}Top
I neglect the Notes from MSDN:
The collection returns only anchor objects that have a
***name or id attribute *** value. If duplicate names are found, a collection of those named items is returned. Collections of duplicate names must be referenced subsequently by ordinal position.
it seems you have to get all elements and examine the anchors individualy.
Top
a useful link:
http://www.experts-exchange.com/Programming/Programming_Languages/MFC/Q_11654078.htmlTop
if(pHTMLDocument)
{
IHTMLElementCollection *pAnchors = NULL;
if(SUCCEEDED(pHTMLDocument->get_all(&pAnchors)))
{
long ilHrefCount = 0;
if(SUCCEEDED(pAnchors->get_length(&ilHrefCount)))
{
long ilHrefIndex = 0;
for(; ilHrefIndex < ilHrefCount; ilHrefIndex++)
{
_variant_t vIndex;
vIndex.vt = VT_I4;
vIndex.lVal = ilHrefIndex;
IDispatch *pItem = NULL;
pAnchors->item(vIndex, vIndex, &pItem);
if(pItem != NULL)
{
IHTMLAnchorElement *pAnchor = NULL;
if(SUCCEEDED(pItem->QueryInterface(IID_IHTMLAnchorElement,
(LPVOID*)&pAnchor)))
{
_bstr_t bURL;
if(SUCCEEDED(pAnchor->get_href(&bURL)))
{
string s = W2A(bURL);
vector<string>::iterator it = find(vstrings.begin(),vstrings.end(),s);
if (it == vstrings.end() && s.length()>0)
vstrings.push_back(s);
}
pAnchor->Release();
}
pItem->Release();
}
}
}
pAnchors->Release();
}
}Top
一个使用JScript的方法,大可不必写VC的程序而且可以作为发布扩展和修改,虽然比较复杂,但是灵活掌握可以做到高扩展性,
文档中除了JSArrayToElementArray是从其他网站上,摘抄下来,其他都是我自己写的,其中JSObjectToAttributes花了我一天
的时间方试出来,这个函数我曾经花了200分在CSDN上询问,无奈无人知晓
我打算专门为JScript和VC的互通性写一套库
本文档仅能使用在VS7.0的版本
VC-JScript:
HRESULT ExecuteScript(IHTMLWindow2* spWin,BSTR bstrScript,VARIANT *pvarRet)
{
HRESULT hr;
VARIANT var;
VariantInit(&var);
if(FAILED(hr=spWin->execScript(CComBSTR("eval(/"/");"),CComBSTR("javascript"),&var)))
return hr;
VariantClear(&var);
DISPID dispid;
CComBSTR bstrName("eval");
if(FAILED(hr=spWin->GetIDsOfNames(IID_NULL,
&bstrName,
1,
LOCALE_SYSTEM_DEFAULT,
&dispid))) return hr;
DISPPARAMS params;
CComVariant varRet;
memset(¶ms,0,sizeof(params));
params.cArgs=1;
params.rgvarg=&var;
var.vt=VT_BSTR;
var.bstrVal=bstrScript;
hr=spWin->Invoke(dispid,IID_NULL,0,DISPATCH_METHOD,¶ms,pvarRet,NULL,NULL);
return hr;
}
HRESULT ExecuteScript(IHTMLWindow2* spWin,LPCTSTR lpszScript,VARIANT *pvarRet)
{
return ExecuteScript(IHTMLWindow2* spWin,CComBSTR(lpszScript),VARIANT *pvarRet)
}
HRESULT ExecuteScript(IHTMLDocument2* spDoc,BSTR bstrScript,VARIANT *pvarRet)
{
HRESULT hr;
CComPtr<IHTMLWindow2> spWin;
if(FAILED(hr=spDoc->get_parentWindow(&spWin)))
return hr;
return ExecuteScript(spWin,bstrScript,pvarRet);
}
HRESULT ExecuteScript(IHTMLDocument2* spDoc,LPCTSTR lpszScript,VARIANT *pvarRet)
{
return ExecuteScript(spDoc,CComBSTR(lpszScript),pvarRet);
}
typedef CSimpleMap<CComBSTR,CComVariant> MapAttr;
HRESULT JSObjectToAttributes(IDispatch* pDisp,MapAttr& map)
//这个函数可以解释动态生成的JSObject的属性
{
CComPtr<ITypeInfo> spInfo;
HRESULT hr;
hr=pDisp->GetTypeInfo(0,LOCALE_SYSTEM_DEFAULT,&spInfo);
if(hr!=S_OK)return hr;
TYPEATTR* pTypeAttr;
hr=spInfo->GetTypeAttr(&pTypeAttr);
if(hr!=S_OK) return hr;
WORD cVars=pTypeAttr->cVars;
spInfo->ReleaseTypeAttr(pTypeAttr);
for(WORD i=0;i<cVars;i++)
{
VARDESC* pVarDesc;
if(spInfo->GetVarDesc(i,&pVarDesc)==S_OK)
{
MEMBERID memid=pVarDesc->memid;
spInfo->ReleaseVarDesc(pVarDesc);
UINT count;
CComBSTR bstrName;
if(spInfo->GetNames(memid,&bstrName,1,&count)==S_OK)
{
CComVariant var;
DISPPARAMS param;
memset(¶m,0,sizeof(param));
hr=pDisp->Invoke(memid,
IID_NULL,
LOCALE_SYSTEM_DEFAULT,
DISPATCH_PROPERTYGET,
¶m,
&var,
NULL,
NULL);
if(SUCCEEDED(hr))
map.Add(bstrName,var);
}
}
}
return S_OK;
}
HRESULT JSArrayToArray(IDispatch* pDisp,CSimpleArray<CComVariant>& arr)
//这个函数获取JSArray元素的函数,其实也可以从JSObjectToAttributes获得
{
HRESULT hr;
DISPPARAMS dispArgs= { NULL, NULL, 0, 0 };
CComVariant var;
hr = pDisp->Invoke( DISPID_NEWENUM,
IID_NULL,
LOCALE_SYSTEM_DEFAULT,
DISPATCH_PROPERTYGET,
&dispArgs,
&var,
NULL,
NULL );
if( FAILED( hr ))
return NULL;
if (var.vt != VT_UNKNOWN && var.vt != VT_DISPATCH)
return NULL;
CComQIPtr<IEnumVARIANT> pEnum( var.punkVal );
if( !pEnum )
return NULL;
hr = S_OK;
while( hr == S_OK )
{
CComVariant elemV;
hr = pEnum->Next( 1, &elemV, NULL );
if( elemV.vt != VT_EMPTY )// correct for dispproxy bug 19307
arr.Add(elemV);
else
hr=S_FALSE;
}
return S_OK;
}
针对你的问题
Javascript文件内容:
var hrefArray=new Array();
var col=document.all.tags("A");
for(var i=0;i<col.length;i++)
hrefArray[hrefArray.length]=col[i].href;
hrefArray
VC内容:
void CLeftView::GetAllRoom(IHTMLDocument2Ptr pDoc)
{
BSTR bstrScript=GetAllRoomScript();
CComVariant varJSArray;
if(SUCCEEDED(ExecuteScript(pDoc,bstrScript,&varJSArray)) && varJSArray.vt==VT_DISPATCH)
{
CSimpleArray<CComVariant> arrHref;
if(SUCCEEDED(JSArrayToArray(varJSArray.pdispVal,arrHref)))
{
//do what ever you want
}
}
}