IE 解析 Web Page DOM结构 (二)

本文深入探讨了在IE浏览器中解析DOM结构时如何处理文字和图像。主要内容包括:从BODY层获取文字及其样式信息,如字体、大小、颜色和位置,以及处理嵌套容器如Table中的文字问题。同时,提到了文字编码和文字分行的挑战,并预告了后续将详述Table中文字的位置解析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

接下来的两篇我将介绍怎样从DOM流中解析出组成网页的最基本的两种元素:文字和图像。

 

上一篇我说过网页是由许多嵌套的frame组成,而每一个frame都是一个独立的单元,他们包含自己的文字和图片。解析文字和图片有以下两种情况:

1.         他们都直接放置在网页“BODY”层,此时我不用考虑这些frame导致的布局影响。这是最简单的一种情形。

2.         而常见的情形是他们被放置于嵌套的frame中,比如Button控件上的文字,TextBox控件中的文字等。

 

l   文字

1.    BODY“层的文字

文字在DOM语言中有好多种标签可以代表他,比如LabelTitle,和Anchor等等。他们都表示有文字。

·         首先,我需要得到文字的位置以及他的本体文字,这可一从IHTMLElement接口中获得。

          IHTMLElement Members(从MSDN摘录的片段)

offsetParent

Retrieves a reference to the container object that defines the IHTMLElement::offsetTop and IHTMLElement::offsetLeft properties of the object.

offsetHeight

Retrieves the height of the object relative to the layout or coordinate parent, as specified by the IHTMLElement::offsetParent property.

offsetLeft

Retrieves the calculated left position of the object relative to the layout or coordinate parent, as specified by the IHTMLElement::offsetParent property.

offsetParent

Retrieves a reference to the container object that defines the IHTMLElement::offsetTop and IHTMLElement::offsetLeft properties of the object.

offsetTop

Retrieves the calculated top position of the object relative to the layout or coordinate parent, as specified by the IHTMLElement::offsetParent property.

offsetWidth

Retrieves the width of the object relative to the layout or coordinate parent, as specified by the IHTMLElement::offsetParent property.

innerText

Sets or retrieves the text between the start and end tags of the object.

下面是可行的伪代码:

                 long ltop, lleft, lHeight, lwidth;

                 hr = spElement->get_offsetLeft(&lleft);

                 hr = spElement->get_offsetTop(&ltop);

                 hr = spElement->get_offsetHeight(&lHeight);

                 hr = spElement->get_offsetWidth(&lwidth);

 

                 BSTR bstrInnerText;

                 hr = spElement->get_innerText(&bstrInnerText);

·         关于文字的字体风格,如字体大小,字体族,是否加粗,倾斜等等,我就只能从CSS流中解析。而CSS流的代表接口就是IHTMLCurrentStyle

 

            IHTMLCurrentStyle Members(从MSDN摘录的片段)

fontFamily

Sets or retrieves the name of the font used for text in the object.

fontSize

Sets or retrieves a value that indicates the font size used for text in the object.

fontStyle

Sets or retrieves the font style of the object as italic, normal, or oblique.

fontVariant

Sets or retrieves whether the text of the object is in small capital letters.

fontWeight

Sets or retrieves the weight of the font of the object.

下面是可行伪代码:

            CComQIPtr<IHTMLElement> spElement;

                          CComQIPtr<IHTMLElement2> spElement2(spElement);        

                          CComQIPtr<IHTMLCurrentStyle>spCurrentStyle;

                          spElement2->get_currentStyle(&spCurrentStyle);

                          VARIANT  varfontSize;

                          varfontSize.vt = VT_BSTR;

                          spCurrentStyle->get_fontSize(&varfontSize);

                          VARIANT varfontWeight;

                          varfontWeight.vt = VT_BSTR;

                          spCurrentStyle->get_fontWeight(&varfontWeight);

                          VARIANT varHeight;

                          varHeight.vt = VT_BSTR

                          spCurrentStyle->get_height(&varHeight);

 

这里你所取得的fontFamily的值是一个字体族列表,其中的每个字体族用分号隔开以防止当有多种字体族混杂在一起。此值主要由两部分组成:字体族名称和通用字体族名称。如果字体族名称包含空白符,它应该出现一个或两个引号;通用字体族名称不用包含在引号中。

为什么要这样组织字体族名称呢?这主要是因为你不知道客户端安装了什么字体, 你应该提供用户一个备用的字体族 通用字体族名称在字体族名称列表的末尾,防止如果客户端没有安装字体族名称指定的字体时,可以用通用字体族名称来替代。

这个字体族名称列表也可以包含嵌入字体。此外,关于fontFamily的默认值可以通过Microsoft Internet Explorer->Internet Options menu->General tab->Fonts button来设置。

综上所述,IE浏览器是这样来应用字体的:首先他会从DOM中解析出fontFamily的字体列表,然后他会尝试其中的每一个字体,直到找到一种客户端已经安装的字体族。如果到列表末尾,IE浏览器依然没有找到相应的字体,那么他就会使用IE设置的那个默认字体。

此外,在上面的伪代码中所得到的字体大小,高度,宽度等数据,他们返回的值有可能不是绝对的数值,如8pt。相反,它可能是一种相对值(相对上一层字体),比如:xx-smallx-smalllargersmaller等等。这不可避免地要求我们自己将这些抽象概念转化为绝对数值。特别是,如果给出的是百分比,我们可能需要递归算出这些数值。

最糟糕的是,有时候你可能取得的是负值,比如:“-1”,“-2”。这意味着字体大小必须转化为设备单位,而且匹配它的绝对数值通过可用字体字符的高度。

·         文字颜色是个很麻烦的问题,可以用下面的代码:

CComQIPtr<IHTMLCurrentStyle>spCurrentStyle;

VARIANT varColor;

varColor.vt = VT_BSTR|VT_I4;

spCurrentStyle->get_color(&varColor);

但是请注意返回的varColor是一个BSTR值,而且是专属于网页设计的一组颜色值,如果你想使用RGB颜色值,必须自己进行转换。而且,DOM常常会简写这个颜色值,比如#00ccff,从上面的代码取出来的值可能是#0cf

·         文字编码问题

我们可以在IE浏览器中设置网页的编码,这些信息我们也可以从DOM中获取.

 

BSTR bstrCharset;

  spHTMLDocument2->get_charset(&bstrCharset);

 

2.    嵌套容器中的文字

我打算以Table控件中的文字为例,其他控件容器中的文字可以按类似的方法来处理

·         Get text in Table

许多网页中都有Table控件,每个Table都有自己的文字。比如,下面这个Table

Hanna Strategies, Ltd. is among the first software outsourcing service providers in China 's IT industry, specializing in the research and development of computer aided design (CAD) and data management software......

这个TableDOM树如下所示:(通过IE Dev Toolbar取得)

 

·         文字分行

网页中的文字是没有分行符让你判断文字该到哪个字分行,这是一个大麻烦,尤其对于那些做文件格式转化的程序员而言。因为这意味着虽然你可以得到上面的那一大段文字,但是,你不知道怎么来断行。唯一可行的办法就是自己设计算法来分行,但只是一件非常复杂的事。

你想一想,你既要考虑字体目前的大小,还要调整Table一行是多宽,从而计算每一行最多可以放几个字。其中,还要加上字跟字,行跟行之间的间距值。这实在是个很烦琐的事。

·         Table中文字的位置

现在文字的位置需要考虑连个因素:一个是文字相对于Table的位置;另一个是整个Table相对于网页的位置。

                 IHTMLTable Members(从MSDN摘录)

align

Sets or retrieves a value that indicates the table alignment.

cellPadding

Sets or retrieves the amount of space between the border of the cell and the content of the cell.

cellSpacing

Sets or retrieves the amount of space between cells in a table.

height

Sets or retrieves the height of the object.

width

Sets or retrieves the width of the object.

 

                 IHTMLTableCell Members(从MSDN摘录)

colSpan

Sets or retrieves the number columns in the table that the object should span.

height

Sets or retrieves the height of the object.

noWrap

Sets or retrieves whether the browser automatically performs wordwrap.

rowSpan

Sets or retrieves how many rows in a table the cell should span.

vAlign

Sets or retrieves how text and other content are vertically aligned within the object that contains them.

width

Sets or retrieves the width of the object.

 

关于这一点我会在后面详细讨论,这也是一个浩大的解析过程。

 

 

 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值