VBGood网站全文搜索 Google

搜索VBGood全站网页(全文搜索)
首页 - 经验之谈 - 利用 Microsoft 的 HTML 分析器来获得 Web 站点的数据
发表评论(0)作者:不详, 平台:VB6.0+Win98, 阅读:13782, 日期:2002-01-07
利用 Microsoft 的 HTML 分析器来获得 Web 站点的数据
Jeremy Rule
Microsoft Corporation
2000年5月
摘要: 本文讨论如何收集来自 Web 的信息,并借助 Internet Explorer 的可重用分析器组件,将它分布到其他 Web 页或数据库。(打印共 7 页)

程序员面临的一个共同任务就是收集 Web 站点的数据,并将它分布到数据库或其他 Web 页。例如,程序员可能需要从气象站点获得天气预报图,从在线股票经纪人那里获得股票报价,以及从新闻站点获得行业新闻。然后,这些信息被放在一个 Web 页上,供 CIO、商人或销售经理使用。或者,也许程序员需要跟踪历来的气象资料,并需要每天将来自气象站的天气预报信息存入数据库。其应用不胜枚举。

过去,这些选择相当受限制。现在,通过使用象 WinInet.dll 这样的 HTTP 组件或许多其他第三方组件,您就可以获取 Web 页,并利用几百种字符串处理功能来获得网页中您所感兴趣的部分。这一技术已在应用,但很不理想。如果您致力于计算机科学(或者有足够的时间),就会为 HTML 创建一个分析器,以标记 Web 页,然后分析您需要的网页部分。不过,由于 Internet Explorer 的体系结构中已包含了可重复使用的用分析器,这些都不需要了。

Internet Explorer 不只是一个程序,更是许多可重复使用组件的集合与容器。在拆取 Web 页时,最有意思的两个组件是 shdocvw.dll 和 mshtml.dll。第一个组件 shdocvw.dll,包含称为 WebBrowser 的 Microsoft(R) ActiveX(R) 控件,它真实地显示 Web 页。在运行 Internet Explorer 时,显示 Web 页的主窗口就是这样的控件。第二个组件 mshtml.dll,含有能分析 WebBrowser 控件中所包含文档的 HTML 分析器。

可能有这种情况,在您的应用程序内部,已经用 WebBrowser 控件来驻留 Web 页,但仍需要重新创建一个小浏览器来启动 Web 页的拆取。

在文件菜单上,请单击新建工程,以创建“标准 EXE”,然后在工程菜单上单击部件,以添加 Microsoft HTML Object Library 和 Microsoft Internet Controls。(见图 1。)


图 1.

在工具箱中,可看见 WebBrowser 组件。拖动其中之一,文本框和主窗体上的命令按钮。将此文本框的 Text 属性设置为 http://moneycentral.msn.com/”,将此命令按钮的 Caption 属性设置为“浏览(&B)”。(见图 2。)


图 2.

双击该命令按钮,然后在事件处理器中放入下列代码,导航至文本框中命名的 Web 站点:
Private Sub Command1_Click()
WebBrowser1.Navigate Text1.Text
End Sub

保存并运行该程序。试着按浏览按钮,导航到文本框中指定的站点。您已经创建了一个基本的 Web 浏览器 — 就其本身而言没什么用,甚至没什么意义,但它却是迈向 Web 拆取技术的第一步。


回到工程中,在代码窗口中选择 WebBrowser1 对象,然后选择 DocumentComplete 的事件处理器。一旦整个 Web 页下载到此浏览器中,即触发该事件:
Private Sub WebBrowser1_DocumentComplete_
(ByVal pDisp As Object, URL As Variant)

End Sub

传递到该事件中的 URL 就是我们导航所至的位置,它在日后确定浏览器所在的页面时将更为有用。WebBrowser 控件有一个属性称为 Document(文档),可将其视为 IHTMLDocument 来处理:

Private Sub WebBrowser1_DocumentComplete(_ ByVal pDisp As Object, URL As Variant)
Dim Doc As IHTMLDocument2
Set Doc = WebBrowser1.Document
//下一步:分析该文档
End Sub

较新的 IHTMLDocument2 具有 IHTMLDocument 中无法使用的特性。可对系统使用 IHTMLDocument 替代老版本的 Internet Explorer,如果您有勇气的话,甚至可以使用 IHTMLDocument3。补充说明一下,我们假设您已经导航到 Word 文档或 XML 文档,而非 HTML 文档。不要将变量 doc 声明为 IHTMLDocument2,可将其声明为 Word 的文档或 XML 的 DOMDocument。

在进行下一步之前,理解 HTML 文档的结构是非常重要的。和 XML 不一样,HTML 文档的组合有一定的自由度。例如,您会遇到未关闭标记的 HTML 文档。HTML 文档确实有某种结构。结构好的 HTML 文档通常具有下列元素:



header information like the <br /> </HEAD> <br /> <BODY> <br /> elements like <TABLE> and <A> and <IMG> <br /> </BODY> <br /></HTML> <br /> <br />请注意 HTML 的树状结构。标记包含标记又包含标记,如此等等。特别是,每一个标记元素都包含一个 0 到 n 个标记元素的集合。<TABLE> 标记可以包含 <TR> 标记。每个 <TR> 标记可以包含 <TD> 标记,后者又可以包含其他标记如锚或图像等。 <br /> <br />现在,分析整个http://moneycentral.msn.com/,并在带 MSFT 符号的页填上第二个 <INPUT> 标记。然后,调用此窗体上的提交: <br />Private Sub WebBrowser1_DocumentComplete(ByVal pDisp As Object, URL As Variant) <br /> Dim doc As IHTMLDocument2 <br /> Set doc = WebBrowser1.Document <br /> <br /> If URL = _ <br /> "http://moneycentral.msn.com/home.asp"; Then <br /> ’填充带输入标记的元素集合 <br /> Dim Inputs As IHTMLElementCollection <br /> Set Inputs = doc.All.tags("INPUT") <br /> ’选择第一个输入标记 <br /> Dim Element As IHTMLElement <br /> Set Element = Inputs.Item(1, 1) <br /> <br /> ’使用正确的界面 <br /> Dim InputElement As IHTMLInputElement <br /> Set InputElement = Element <br /> InputElement.value = Text1.Text <br /> <br /> ’调用此页第一个窗体上的提交 <br /> doc.Forms.Item(0, 0).submit <br />End Sub <br /> <br />在此您会看到,标记集合如何包含可视为其特定类型的标记。每一个标记都可用 IHTMLElement 界面表示,或用指定为该标记类型的界面表示。例如,<TABLE> 标记可用 IHTMLTableElement 或 IHTMLElement 表示。 <br /> <br />标记的集合都包含下列重要的方法和属性: <br /> <br />长度。可将其理解为计数,或集合中项目的数量。 <br /> <br /> <br />项目。用于选择集合中的特殊元素。“项目”有两个参数,第二个参数即命名的标记。 <br /> <br /> <br />标记。将要过滤的元素传递给标记。标记 ("A") 将返回集合内所有锚的集合。要想有效地拆取页,就需要学会使用标记集合。 <br />现在可能您会问,“为什么不直接转到http://moneycentral.msn.com/scripts/webquote.dll?ipage=qd&Symbol=msft?”当然是可以的,但这个例子告诉大家如何在更复杂的情况下操纵 HTML 窗体。 <br /> <br />如果您未做进一步的改动即运行该程序,就会注意到它将陷入无休止的循环,没完没了地下载同一个页面。程序不断地寻找要填充的窗体,并反复调用 DocumentComplete。要修正这个缺陷,应在 DocumentComplete 中置入一些逻辑,告诉分析器,只有在正确的页面上才提交窗体。 <br /> <br />接下来,让我们放入这个逻辑,并引入实际的股票报价。另外,我们不捕获文本框中的 URL,而是捕获股票符号: <br />Private Sub Command1_Click() <br /> WebBrowser1.Navigate _ <br /> "http://moneycentral.msn.com/home.asp"; <br />End Sub <br />Private Sub WebBrowser1_DocumentComplete(ByVal pDisp As Object, URL As Variant) <br /> Dim doc As IHTMLDocument2 <br /> Set doc = WebBrowser1.Document <br /> <br /> If URL = "http://moneycentral.msn.com/home.asp"; Then <br /> ’填充带输入标记的元素集合 <br /> Dim Inputs As IHTMLElementCollection <br /> Set Inputs = doc.All.tags("INPUT") <br /> ’选择第一个输入标记 <br /> Dim Element As IHTMLElement <br /> Set Element = Inputs.Item(1, 1) <br /> <br /> ’使用正确的界面 <br /> Dim InputElement As IHTMLInputElement <br /> Set InputElement = Element <br /> InputElement.value = Text1.Text <br /> <br /> ’调用该页第一个窗体上的提交 <br /> doc.Forms.Item(0, 0).submit <br /> ElseIf URL = _ <br /> "http://moneycentral.msn.com/scripts/webquote.dll?ipage=qd&Symbol="; _ <br /> & Text1.Text Then <br /> Dim Tables As IHTMLElementCollection <br /> Set Tables = doc.All.tags("TABLE") <br /> ’获得第 14 个表的第二个项目(基于 0) <br /> Dim Quote As IHTMLElement <br /> Set Quote = _ <br /> Tables.Item(14, 14).All.tags("TD").Item(2, 2) <br /> ’显示开始标记和结束标记之间的文本 <br /> MsgBox Quote.innerText <br /> End If <br />End Sub <br /> <br /> <br /> <br />图 3. <br /> <br />到了这最后一步,自定义的浏览器已被转入有效的 Web 拆取器。重要的是,要注意有了 IHTMLElement 之后获得文本的可用选项。有 4 个属性: <br /> <br />innerText:开始标记和结束标记之间的文本。 <br /> <br /> <br />innerHTML:开始标记和结束标记之间的文本和 HTML。 <br /> <br /> <br />outerText:对象的文本。 <br /> <br /> <br />outerHTML:对象的文本和 HTML。 <br />还要注意从第 4 个表(基于 0)的第 11 个元素中检索到的最终报价字符串。如果 MoneyCentral? 决定重新调整该页怎么办?您最好的策略是根据合理的假定来查询页面。如果您知道报价几乎总是放在新闻标题的前面,那么就从新闻标题往回查询那个表。还有一种策略是,当更改页面的格式时,有一种简单的方法来更新分析器。一种方法就是将分析的职能细分为较小的组件。每个组件可以实现一个预定义的界面,接受要分析的 IHTMLDocument。与实际的 Web 页失去同步的分析组件可被替换。这样带来的好处是,多个编程人员都可以编写分析器,只需给定要实现的界面和要拆取的 Web 站点即可。 <br /> <br />为了避免复杂,将 IHTMLDocument 从 DocumentComplete 函数传递 COM DLL,后者可以分析 IHTMLDocument 并返回想要的有效负载。这有利于程序的模块化,并易于更新与 Web 站点失去同步的分析部分。它还使多个开发者能同时处理这个项目,因为他们有一个干净的界面来编写分析器。 <br /> <br />在把新的程序推向市场以前,还有几个实际问题要考虑。首先,很可能 MoneyCentral 和其他许多站点不愿意别人下载他们的内容,也不喜欢看广告。您可能得与摘取其内容的站点签订一份协议。 <br /> <br />还有很重要的一点要注意,即如果您是 Web 站点的操作员,那么还有更好的办法将您的内容提供给其他系统。虽然可以让其他人来拆取您的 Web 页,但这仍很笨拙。还有一个更好的方法是,提供 XML 来表现内容。并且,随着 XML 被广泛采用,Web 站点开始提供其数据的 XML 表现形式以及 HTML 界面,也不值得大惊小怪。在这样的时刻到来之前,您也许还得拆取 Web 页。Web 页的拆取往往失之笨拙,但 Microsoft HTML 分析器可令其稍微好一些。 </div><div class="center"><script type="text/javascript">google_ad_client="pub-0299651374046766";google_ad_slot="0254962310";google_ad_width=728;google_ad_height=90;</script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script></div><div id="article"> <ul class="tabs"> <li><a>评论(0)</a></li> <li><a>发表评论</a></li> </ul> <div class="tabText"> </div> <div class="tabText" click="dc.comment.form(1, 'article',3601)"> </div> </div> </div></div> <div id="left"><dl class="dlist"> <dt><strong>VBGood RSS 订阅</strong></dt> <dd><ul id="rss"> <li class="small red">每周超过200个关于VB编程的精彩新话题,现在就订阅吧!</li> <li><a rel="nofollow" href="http://fusion.google.com/add?feedurl=http://feeds2.feedburner.com/vbgood" target="_blank" title="订阅到 google reader"><img alt="google reader" src="/public/images/rss_google.gif" /></a></li> <li><a rel="nofollow" href="http://www.zhuaxia.com/add_channel.php?url=http://feeds2.feedburner.com/vbgood" target="_blank" title="订阅到 抓虾"><img alt="抓虾" src="/public/images/rss_zhuaxia.gif" /></a></li> <li><a rel="nofollow" href="http://add.my.yahoo.com/rss?url=http://feeds2.feedburner.com/vbgood" target="_blank" title="订阅到 my yahoo"><img alt="my yahoo" src="/public/images/rss_yahoo.gif" /></a></li> <li><a rel="nofollow" href="http://www.bloglines.com/sub/http://feeds2.feedburner.com/vbgood" target="_blank" title="订阅到 bloglines"><img alt="bloglines" src="/public/images/rss_bloglines.gif" /></a></li> <li><a rel="nofollow" href="http://www.xianguo.com/subscribe.php?url=http://feeds2.feedburner.com/vbgood" target="_blank" title="订阅到 鲜果"><img alt="鲜果" src="/public/images/rss_xianguo.gif" /></a></li> <li><a rel="nofollow" href="http://feeds2.feedburner.com/vbgood" target="_blank" title="订阅本站"><img src="/public/images/rss.gif"> RSS地址</a></li> </ul></dd> </dl><dl class="dlist"> <dd class="right" style="line-height:1em"><h4 class="small"><a href="/article-categoryid-5.html" rel="nofollow">更多...</a></h4></dd> <dt><strong>同类文章</strong></dt> <dd><ul><li class="listli" onmouseover="this.style.backgroundColor='#E1E1E1'" onmouseout="this.style.backgroundColor=''"><a href="/article-122.html" target="_blank">许多用VB编的软件,当选择“关于”时,其中的Email地址和主页网址都是蓝色带下划线的链接形式</a></li><li class="listli" onmouseover="this.style.backgroundColor='#E1E1E1'" onmouseout="this.style.backgroundColor=''"><a href="/article-121.html" target="_blank">在VB中用Outlook发电子邮件</a></li><li class="listli" onmouseover="this.style.backgroundColor='#E1E1E1'" onmouseout="this.style.backgroundColor=''"><a href="/article-120.html" target="_blank">使用标签控件调出浏览器</a></li><li class="listli" onmouseover="this.style.backgroundColor='#E1E1E1'" onmouseout="this.style.backgroundColor=''"><a href="/article-119.html" target="_blank">用VB5.0设计E-Mail程序</a></li><li class="listli" onmouseover="this.style.backgroundColor='#E1E1E1'" onmouseout="this.style.backgroundColor=''"><a href="/article-118.html" target="_blank">如何启动拨号网路中的连线</a></li><li class="listli" onmouseover="this.style.backgroundColor='#E1E1E1'" onmouseout="this.style.backgroundColor=''"><a href="/article-117.html" target="_blank">利用IE控件访问Internet</a></li><li class="listli" onmouseover="this.style.backgroundColor='#E1E1E1'" onmouseout="this.style.backgroundColor=''"><a href="/article-116.html" target="_blank">用Winsock实现点对点通信</a></li><li class="listli" onmouseover="this.style.backgroundColor='#E1E1E1'" onmouseout="this.style.backgroundColor=''"><a href="/article-115.html" target="_blank">用VB5开发IE</a></li><li class="listli" onmouseover="this.style.backgroundColor='#E1E1E1'" onmouseout="this.style.backgroundColor=''"><a href="/article-114.html" target="_blank">自己的IE——用VB制作浏览器?</a></li><li class="listli" onmouseover="this.style.backgroundColor='#E1E1E1'" onmouseout="this.style.backgroundColor=''"><a href="/article-113.html" target="_blank">检测运程数据传送的断线</a></li></ul></dd> </dl><dl class="dlist"> <dt><strong>随机文章</strong></dt> <dd><ul><li class="listli" onmouseover="this.style.backgroundColor='#E1E1E1'" onmouseout="this.style.backgroundColor=''"><a href="/article-210.html" target="_blank">使用 API 开始屏幕保护</a></li><li class="listli" onmouseover="this.style.backgroundColor='#E1E1E1'" onmouseout="this.style.backgroundColor=''"><a href="/article-3047.html" target="_blank">给TreeView控件添加节点一例</a></li><li class="listli" onmouseover="this.style.backgroundColor='#E1E1E1'" onmouseout="this.style.backgroundColor=''"><a href="/article-508.html" target="_blank">如何抓出 Access 的 Table 表中的【敘述】部份呢</a></li><li class="listli" onmouseover="this.style.backgroundColor='#E1E1E1'" onmouseout="this.style.backgroundColor=''"><a href="/article-733.html" target="_blank">用VISUAL BASIC6.0开发猜数字小游戏</a></li><li class="listli" onmouseover="this.style.backgroundColor='#E1E1E1'" onmouseout="this.style.backgroundColor=''"><a href="/article-3602.html" target="_blank">如何在VB中截获shell程序的输出</a></li><li class="listli" onmouseover="this.style.backgroundColor='#E1E1E1'" onmouseout="this.style.backgroundColor=''"><a href="/article-801.html" target="_blank">又个用用VB制作屏幕保护程序</a></li><li class="listli" onmouseover="this.style.backgroundColor='#E1E1E1'" onmouseout="this.style.backgroundColor=''"><a href="/article-2587.html" target="_blank">用FileSystemObject检测光驱的盘符</a></li><li class="listli" onmouseover="this.style.backgroundColor='#E1E1E1'" onmouseout="this.style.backgroundColor=''"><a href="/article-3435.html" target="_blank">妙用GetSystemMetrics函数</a></li><li class="listli" onmouseover="this.style.backgroundColor='#E1E1E1'" onmouseout="this.style.backgroundColor=''"><a href="/article-2403.html" target="_blank">用 VB 实现新闻眼(提取搜狐的当天新闻),刚写的文章(准备投稿用的),大家先看为快吧,再提点见意!!</a></li><li class="listli" onmouseover="this.style.backgroundColor='#E1E1E1'" onmouseout="this.style.backgroundColor=''"><a href="/article-2385.html" target="_blank">提高开发VB应用程序的效能</a></li></ul></dd> </dl></div> <div class="clear"></div> </div> <!-- footer --> <div id="footer"> <span class="right">85.35ms | <a href="/about.html">关于我们</a> | <a href="/advertise.html" rel="nofollow">广告服务</a> | <a href="/weblink.html" rel="nofollow">友情链接</a> | <a href="/contact.html" rel="nofollow">联系方式</a> | <a href="/privacy.html" rel="nofollow">隐私条款</a> | <a href="/cooperate.html" rel="nofollow">合作事宜</a> | <a href="/history.html">网站历史</a> | <a href="http://feeds2.feedburner.com/vbgood" target="_blank"><img src="/public/images/rss.gif" width="15" height="16" alt="VBGood RSS供稿订阅" title="VBGood RSS供稿订阅" /></a> | <a href="javascript:scroll(0,0)" rel="nofollow">Top</a></span> CopyRight © 2000-2020 VBGood.com <div class="clear"></div> </div> <div id="link">Link: <a href="http://www.wisdom.hk" target="_blank">WISDOM Cap Lamp</a> <a href="http://www.wisdom-pen.com" target="_blank">Wisdom Pen</a> <a href="http://www.li-ion.net" target="_blank">Li-ion</a> <a href="http://www.li-ion-battery.com" target="_blank">Li-ion Battery</a> <a href="http://www.n-wisdom.com" target="_blank">New Wisdom</a> <a href="http://www.limn2o4.com" target="_blank">LiMn2O4</a> <a href="http://www.caplamp.org" target="_blank">Cap Lamp</a> <a href="http://www.vbgood.cn" target="_blank">VBGood.cn</a> <a href="http://www.minerlamp.org" target="_blank">Miner's Lamp</a> <a href="http://www.caplamp.net" target="_blank">Cap Lamp</a> <a href="http://www.wisdomflashlight.com" target="_blank">Flashlight</a> <a href="http://www.pocketlamp.cn" target="_blank">PocketLamp</a> <a href="http://www.265.com/Chengxu_Biancheng/" target="_blank">Google网站导航-编程</a> </div> </div> </body> </html>