MsHtml的问题: 如何取得页面上所有显示的内容?

gbstar2021 2001-11-17 05:54:32
例如:这样一个 html 文件
<html>
<head>
</head>
<body>
abcdefg
<input type="text" name="myid" size="10" value="abc">
abcd
<select size="1" name="type">
<option value="1" selected>select1</option>
<option value="2">select2</option>
<option value="3">select3</option>
</select>
abcd
</body>
</html>

如何不直接访问 html 的前提下,取得页面上正在显示所有的文本内容呢(包括 text 中填写的内容,select 中选择的文本内容)?

就是说,怎么把页面上的普通的文本、编辑框中的文本、组合框中的文本加起来成为一个完整的内容?

IHTMLElement::get_innerText() 可以取得内容,但是不太符合要求,请教各位有没有其他的办法
...全文
529 19 打赏 收藏 举报
写回复
19 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
sungang 2001-11-20
是一种解决问题的办法。
请问:当HTML页面内容很多时,比如有30-50K文本,get_innerText的效率非常低,不知道哪位知道原因?

欢迎下载我们的软件
http://www.csdn.net/cnshare/soft/4/4632.html
  • 打赏
  • 举报
回复
gbstar2021 2001-11-20
代码写得比较粗糙,不太好意思贴出来 :-)

#include <afxconv.h>
#include <atlbase.h>
#include <mshtml.h>


void CMyHtmlView::GetHtmlText()
{
USES_CONVERSION;
////////////////////////
CComQIPtr<IHTMLDocument2,&IID_IHTMLDocument2> pDoc(GetHtmlDocument());
if(pDoc==NULL)
return;
//////////////////////////////////////////////////////////////////////////
CComPtr<IHTMLElementCollection> pAll;
pDoc->get_all(&pAll);
if(pAll==NULL)
return;
// replace <input>
{
CComPtr<IDispatch> pDispAllText;
pAll->tags(COleVariant("Input"),&pDispAllText);
CComQIPtr<IHTMLElementCollection,&IID_IHTMLElementCollection> pAllText(pDispAllText);
if(pAllText==NULL)
return;
long num=0;
pAllText->get_length(&num);
for(long i=0;i<num;++i)
{
CComPtr<IDispatch> pDispText;
COleVariant vName;
COleVariant vIndex(i);
pAllText->item(vName,vIndex,&pDispText);

CComQIPtr<IHTMLInputTextElement,&IID_IHTMLInputTextElement> pText(pDispText);
if(pText!=NULL)
{
// pText->put_value(T2OLE("(#################)"));
BSTR str;
pText->get_value(&str);
CComQIPtr<IHTMLElement,&IID_IHTMLElement> pTextElem(pDispText);
pTextElem->put_outerHTML(str);
SysFreeString(str);
}
}
}
// replace <select>
{
CComPtr<IDispatch> pDispAllSelect;
pAll->tags(COleVariant("select"),&pDispAllSelect);
CComQIPtr<IHTMLElementCollection,&IID_IHTMLElementCollection> pAllSelect(pDispAllSelect);
if(pAllSelect==NULL)
return;
long num=0;
pAllSelect->get_length(&num);
for(long i=0;i<num;++i)
{
CComPtr<IDispatch> pDispSelect;
COleVariant vName;
COleVariant vIndex(i);
pAllSelect->item(vName,vIndex,&pDispSelect);

CComQIPtr<IHTMLSelectElement,&IID_IHTMLSelectElement> pSelect(pDispSelect);
if(pSelect==NULL)
return;
// get selected item number
BSTR strSelect;
BSTR strText;
pSelect->get_value(&strSelect);
// get selected text
{
COleVariant vName;
COleVariant vIndex(atol(OLE2T(strSelect)));
CComPtr<IDispatch> pDispOptions;
pSelect->item(vName,vIndex,&pDispOptions);
CComQIPtr<IHTMLOptionElement,&IID_IHTMLOptionElement> pOptions(pDispOptions);
if(pOptions!=NULL)
pOptions->get_text(&strText);
}
// replace select
CComQIPtr<IHTMLElement,&IID_IHTMLElement> pSelectElem(pDispSelect);
pSelectElem->put_outerHTML(strText);
// free
SysFreeString(strText);
SysFreeString(strSelect);
}
}

// display all text in htmlview
CComPtr<IHTMLElement> pBody;
pDoc->get_body(&pBody);
BSTR str;
pBody->get_innerText(&str);
MessageBox(OLE2T(str));
SysFreeString(str);
}
  • 打赏
  • 举报
回复
nomy 2001-11-20
if you get inner text of select element, the function usually return an empty
string.
so if you really want to get the inner text of select element, you must
get the inner text of all option element under the select element.
a better alternative is IHTMLDOMNode interface.
each text and element has a corresponding node in IHTMLDOMNode tree.
query this interface from IHTMLElement
  • 打赏
  • 举报
回复
tkutt 2001-11-19
如何解决的?
能否贴出来共享?
  • 打赏
  • 举报
回复
gbstar2021 2001-11-19
问题解决了
  • 打赏
  • 举报
回复
smallfool 2001-11-19
是啊,能否共享?或者给我一分:smallfool@yeah.net 不甚感激
  • 打赏
  • 举报
回复
smallfool 2001-11-18
那你就要看什么功能了.一个接口对应一定的功能.你要首先搞清楚各个接口的功能.顺便问一句;你是如何得到代码的?URLDownload???
  • 打赏
  • 举报
回复
蒋晟 2001-11-18
编辑框中的文本、组合框中的文本可以换成SPAN
用HRESULT IHTMLInputElement::get_value(BSTR *p);获得当前<INPUT>输入的值,然后把换成<SPAN>再存盘。
  • 打赏
  • 举报
回复
ray2_ls 2001-11-17
特来学习!
  • 打赏
  • 举报
回复
gbstar2021 2001-11-17
保存HTML的代妈很容易,但是我不想直接去访问它的代码,我想通过提供的接口实现功能
  • 打赏
  • 举报
回复
smallfool 2001-11-17
我看过一些资料,说可以从内存中读入HTML,相关资料似乎还说明可以用IPersistStream/IPesistStorage接口来将HTML保存下来,我一直想试试,可是似乎不的要法,前者很容易,后者谁试过?如果你将HTML保存下来,想想你对它的任何操作就都可以完成了.
  • 打赏
  • 举报
回复
gbstar2021 2001-11-17
to jiangsheng

只关心文本的内容,其余的都可以忽略,包括表格。
  • 打赏
  • 举报
回复
蒋晟 2001-11-17
那表格和图形怎么办?比如计数器,通常都是图形的
可以在保存之前把一些元素换掉,比如<INPUT>。
  • 打赏
  • 举报
回复
Jneu 2001-11-17
g~z
  • 打赏
  • 举报
回复
gbstar2021 2001-11-17
to smallfool:

遍历之后确实可以取得对象(text,select)的文本内容,不过怎样才能把这些文本放回原来的位置呢?
  • 打赏
  • 举报
回复
smallfool 2001-11-17
你还可以通过遍历所有对象的办法来获得所有的文本,不过 这样似乎有重复.
  • 打赏
  • 举报
回复
smallfool 2001-11-17
请看下面的代码:
CXXXView:GetBodyText(IHTMLDocument2* pDoc)
{
ASSERT(pDoc!=NULL);
IHTMLElement *pElem = NULL;

pDoc->get_body(&pElem);

_bstr_t bstText;
BSTR bsText;
HRESULT hr = pElem->get_innerText(&bsText);
if(SUCCEEDED(hr))
{
bstText = bsText;
SysFreeString(bsText);
}
pElem->Release();
return (LPCTSTR)bstText;
}
//在这里获得IHTMLDocument2接口
CXXXView::DocumentComplete(LPDISPATCH pDisp,VARIANT* URL)
{
HRESULT hr;
LPUNKNOWN lpUnknown = NULL;
LPUNKNOWN lpUnknownWB = NULL;
LPUNKNOWN lpUnknownDC = NULL;

lpUnknown = m_wndBrowser.GetControlUnknown();
ASSERT(lpUnknown);

if (lpUnknown)
{
// Get the IUnknown of the WebBrowser control being hosted.
// The IUnknown returned from GetControlUnknown is not the
// IUnknown of the WebBrowser control. It's actually a
// IOleObject pointer.
//
hr = lpUnknown->QueryInterface(IID_IUnknown, (LPVOID*)&lpUnknownWB);

ASSERT(SUCCEEDED(hr));

if (FAILED(hr))
return;

// Get the IUnknown of the object that fired this event.
//
hr = pDisp->QueryInterface(IID_IUnknown, (LPVOID*)&lpUnknownDC);


ASSERT(SUCCEEDED(hr));

if (SUCCEEDED(hr) && lpUnknownWB == lpUnknownDC)
{
// The document has finished loading.
//
LPDISPATCH pDispatch = GetHtmlDocument();
if (pDispatch)
{
hr = pDispatch->QueryInterface(IID_IHTMLDocument2,(LPVOID*)&m_pHtmlDocument);

pDispatch->Release();
}
}
if (lpUnknownWB)
lpUnknownWB->Release();

if (lpUnknownDC)
lpUnknownDC->Release();
}
}
  • 打赏
  • 举报
回复
gbstar2021 2001-11-17
ctrl-a,再ctrl-c,然后到notepad里ctrl-v 的结果和 get_innerText 应该是一样的
  • 打赏
  • 举报
回复
westaf 2001-11-17
用dom不太可能完成,即使能也很麻烦。

但考虑ie本身是一个ole document server,可以试试ole中的方法。原理:在ie里ctrl-a,再ctrl-c,然后到notepad里ctrl-v,得到的是你想要的结果吗?
  • 打赏
  • 举报
回复
相关推荐
发帖
HTML/XML

3058

社区成员

VC/MFC HTML/XML
社区管理员
  • HTML/XML社区
加入社区
帖子事件
创建了帖子
2001-11-17 05:54
社区公告
暂无公告