使用MSHTML解析网页

temolo 2008-04-04 11:52:43
怎么使用MSHTML提取网页上的所有元素,以NODE树的形式显示出来
最好能给点现成源码,谢谢
...全文
375 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
shuaichi1990 2012-05-15
  • 打赏
  • 举报
回复
// 打开网页
bool CDomTreeDlg::fProcessDOM(void)
{
UpdateData(TRUE);
//取得网页内容
IWebBrowser2* pWebBrowser = NULL;
HRESULT hr = CoCreateInstance(CLSID_InternetExplorer,NULL,CLSCTX_LOCAL_SERVER,IID_IWebBrowser2,(void**)&pWebBrowser );

if( FAILED(hr) )
{
AfxMessageBox("WebBrowser2接口失败");
return FALSE;
}

CComVariant varUrl( m_domURL.GetBuffer(255));
CComVariant var;

hr = pWebBrowser->Navigate2( &varUrl,&var,&var,&var,&var ); // 打开网页
if( FAILED(hr) ) return FALSE;

READYSTATE readystate;
hr = pWebBrowser->get_ReadyState(&readystate); // 查询组建状态
if( FAILED( hr ) ) return FALSE;

while( READYSTATE_COMPLETE != readystate ) // 网页下载,完成后等待循环结束
{
Sleep(50);
pWebBrowser->get_ReadyState(&readystate);
}

CComPtr<IDispatch>pDisp; // COM组件的调度接口
pWebBrowser->get_Document( &pDisp ); // 获得自动化文档对象
CComQIPtr< IHTMLDocument2 >pDoc2( pDisp ); // 此接口获取HTML文件的信息,并审查和修改HTML元素和文本。
PrepareDOMTree(pDoc2);
return TRUE;
}

// 构建DOM树的准备工作
bool CDomTreeDlg::PrepareDOMTree(CComQIPtr<IHTMLDocument2> pDoc)
{
CComQIPtr<IHTMLDocument3> spDoc3 = pDoc; // 此接口提供文件对象的额外的属性和方法。
bool bRet = spDoc3 != NULL;
if( !bRet ){
ATLASSERT(0);
return bRet;
}
CComPtr <IHTMLElement> spRootElement; // 此接口提供了访问所有元素对象共同的属性和方法的能力
bRet = SUCCEEDED( spDoc3-> get_documentElement( &spRootElement));
if( !bRet ) return bRet;

CComQIPtr <IHTMLDOMNode> spRootNode = spRootElement; // 此接口提供方法来访问所有在文档对象模型(DOM)中的节点
bRet = spRootNode != NULL;
if ( !bRet ) return bRet;

std::queue<HTREEITEM> queue_tree_nodes; // 存储树形控件的每个节点的句柄
std::queue<CComQIPtr<IHTMLDOMNode>> queue_DOMNodes; // 存储DOM节点
queue_tree_nodes.push(TVI_ROOT);
queue_DOMNodes .push(spRootNode);
while( !queue_tree_nodes.empty())
{
CComQIPtr<IHTMLDOMNode> spDOMNode = queue_DOMNodes.front(); // 提取表的前端
HTREEITEM parent = queue_tree_nodes.front ();
queue_DOMNodes.pop();
queue_tree_nodes.pop();
HTREEITEM thisnode = InsertDOMNode(spDOMNode, parent); // 向树中插入一个DOM节点
CComPtr<IDispatch> spCollectionDispatch; // COM组件的调度接口
if ( SUCCEEDED( spDOMNode->get_childNodes( & spCollectionDispatch)))
{
long numChildren = 0;
// 该接口提供方法来存取子节点的集合。
CComQIPtr<IHTMLDOMChildrenCollection> spCollection = spCollectionDispatch;
if (NULL != spCollection)
{
spCollection->get_length( & numChildren); // 获取集合中子节点的个数
for ( long i = 0; i < numChildren; i++)
{
CComPtr<IDispatch> spItemDispatch;
spCollection->item( i , &spItemDispatch); // 获取指定索引位置的子节点
if (NULL != spItemDispatch)
{
CComQIPtr<IHTMLDOMNode> spItemNode = spItemDispatch;
if (NULL != spItemNode)
{
queue_DOMNodes.push(spItemNode); // DOM节点放入容器
queue_tree_nodes.push(thisnode); // 树的节点类型放入容器
}
}
}
}
}
}
return bRet; // 返回操作是否完成
}


// 向树中插入一个DOM节点
HTREEITEM CDomTreeDlg::InsertDOMNode(IHTMLDOMNode* pINode, HTREEITEM hparent)
{
//CComPtr<IDispatch> spCollectionDispatch;
CComPtr<IHTMLDOMNode> spNode(pINode);
CComBSTR NodeName; // 标准BSTR是一个有长度前缀和null结束符的OLECHAR数组
TV_INSERTSTRUCT tvis; // 该结构包含添加新项到树形视控件所使用的信息
tvis.hParent = hparent; // 父项的句柄
tvis.hInsertAfter = TVI_LAST; // 插入的新项之后的项的句柄=在列表的最后插入项
tvis.item.mask = TVIF_TEXT | TVIF_PARAM; // 设置树结构成员有效性屏蔽位
if ( SUCCEEDED( spNode->get_nodeName( & NodeName)))
{
CString strNodeName( NodeName); // !这里是标签名字
tvis.item.pszText= _strdup(strNodeName); // 复制字符串s:char *strdup(char *s);
}
// 需要AddRef因为我们将会保持接口指针作为treeview的数据项
pINode->AddRef(); // COM组件增加引用计数
tvis.item.lParam = reinterpret_cast<LPARAM>(pINode); // 消息的发送者传递结构的指针
HTREEITEM hthisItem = m_domTree.InsertItem( &tvis ); // 插入一个树项
if ( hthisItem == NULL)
{
pINode->Release(); // COM组件减少引用计数
return NULL;
}
return hthisItem;
}
PANTI 2010-09-16
  • 打赏
  • 举报
回复
我只会添加到ListBox
xisiyong 2010-09-15
  • 打赏
  • 举报
回复
分享一下。。。
SQLDebug_Fan 2010-09-15
  • 打赏
  • 举报
回复
贴出来给大家分享一下。
wyzyyq 2010-09-15
  • 打赏
  • 举报
回复
咋么啥也没说呢。
UltraBejing 2008-04-30
  • 打赏
  • 举报
回复
这个简单啊,网上搜一下就得到答案了.
手指风 2008-04-06
  • 打赏
  • 举报
回复
别一开口就问源码,这样别人会对你反感的。
UndefinedCoder 2008-04-06
  • 打赏
  • 举报
回复
因为你开口就要代码,差点就要骂了。。

既然搞定了就接点 吧
temolo 2008-04-06
  • 打赏
  • 举报
回复
我已经知道怎么搞了,来了的给分啊
temolo 2008-04-04
  • 打赏
  • 举报
回复
顶下

829

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 非技术区
社区管理员
  • 非技术区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧