免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: niaya
打印 上一主题 下一主题

问个关于Html标签整理的问题 [复制链接]

论坛徽章:
3
戌狗
日期:2014-09-10 17:07:162015年辞旧岁徽章
日期:2015-03-03 16:54:15wusuopu
日期:2016-06-17 17:43:45
21 [报告]
发表于 2009-02-10 10:14 |只看该作者
原帖由 niaya 于 2009-2-10 09:30 发表
不好意思,上面的代码还是没太研究明白。
你给出的(6楼那段代码)应该是只对<span lang=XXX style=YYYYY>进行了处理吧。(变成了<span style=YYYYY>)
但是其他的<span>标签,比如说<span face=XXX><span lang=XXXX><span class=XXX>这样的TAG应该没有处理吧。

我那种写法的话,出来的结果是删掉了所有的span标签,但是现在还希望保留<span style=XXXX></span>这对标签。
我是Perl新手,有些地方看不大明白,还请多多赐教.

6楼代码。
1)找到<p>节点
2)找出带lang=xxx那个<span>, 删除其lang属性,把该span赋值给$mainspan($mainspan中不包含内容,只是<span style="font-size....></span)。
3)把所有<span>节点的内容直接赋值给<p>节点。得到<p ...><b> perl </b> .....</p>。
4)把p节点的内容detach掉(并不删除),
5)把内容attach到$mainspan.
     得到<p ...><span style="font-size...><b> Perl </b> .... </span></p>

[ 本帖最后由 ynchnluiti 于 2009-2-10 10:19 编辑 ]

论坛徽章:
3
戌狗
日期:2014-09-10 17:07:162015年辞旧岁徽章
日期:2015-03-03 16:54:15wusuopu
日期:2016-06-17 17:43:45
22 [报告]
发表于 2009-02-10 10:18 |只看该作者

回复 #20 ynchnluiti 的帖子

  1. {
  2.     my $h = HTML::TreeBuilder->new_from_content( decode($encode, $html) );

  3.     my $p = $h->look_down(_tag => q{p}); # 1) 找到最外层的p节点

  4.     my $mainspan;
  5.     for my $span( $h->look_down(_tag => q{span}) ){ #2
  6.         if ( defined $span->attr('lang') ) {
  7.             $span->attr(lang=>undef);         #删除lang属性
  8.             $mainspan = $span;                    #用$mainspan记录该span节点
  9.             last;
  10.          }
  11.     }
  12. #print decode_entities($mainspan->as_HTML), "\n";

  13.     for my $span( $h->look_down(_tag => q{span}) ){  # 3)把所有span节点的内容直接赋值给,span节点的父节点(即前面找到的$p
  14.         $span->replace_with_content($span->content_refs_list);
  15.     }

  16.     my @content = $p->content_list;
  17.     $p->detach_content();                                                # 4) detach掉$p的内容,因为要放在$mainspan里

  18.     $mainspan->push_content(@content);
  19.     $p->push_content($mainspan);                                 #  5) 把内容放在$mainspan里

  20.     print encode( $encode, $h->as_HTML('<>&',' ',{}) ), "\n";

  21.     $h->delete;
  22. }
复制代码

论坛徽章:
0
23 [报告]
发表于 2009-02-10 10:58 |只看该作者
原帖由 ynchnluiti 于 2009-2-10 10:18 发表
{
    my $h = HTML::TreeBuilder->new_from_content( decode($encode, $html) );

    my $p = $h->look_down(_tag => q{p}); # 1) 找到最外层的p节点

    my $mainspan;
    for my $span( $h->look_d ...


谢谢你的解释,原来问题是在这里,“1) 找到最外层的p节点“
我的那个需求写的只是举个例子,正常html都是有多个段落(也就是多个P节点)的。

$h->look_down(_tag => q{p}); 这个是最外层的话。
如何继续向下查找呢?
应该就差这一步了

论坛徽章:
3
戌狗
日期:2014-09-10 17:07:162015年辞旧岁徽章
日期:2015-03-03 16:54:15wusuopu
日期:2016-06-17 17:43:45
24 [报告]
发表于 2009-02-10 11:01 |只看该作者
原帖由 niaya 于 2009-2-10 10:58 发表


谢谢你的解释,原来问题是在这里,“1) 找到最外层的p节点“
我的那个需求写的只是举个例子,正常html都是有多个段落(也就是多个P节点)的。

$h->look_down(_tag => q{p}); 这个是最外层的话。
如何继 ...

那就要根据情况了。<p>有可能是并列或者嵌套。跟找span的方法类似。

用合适的方法定位要找的<p>节点,比如根据属性,或者父节点、子节点,

论坛徽章:
0
25 [报告]
发表于 2009-02-10 16:06 |只看该作者
原帖由 ynchnluiti 于 2009-2-10 11:01 发表

那就要根据情况了。有可能是并列或者嵌套。跟找span的方法类似。

用合适的方法定位要找的节点,比如根据属性,或者父节点、子节点,


目前我的情况应该算是并列,就是一段一个<p style=XXX> 段末</p>

这种情况下应该如何应对比较好呢? 每一段属性都差不多。怎么提取能便捷些。

这样的html

<body>

<p style=XXX>AAAA<span class=A>BBBB<span lang=en-us style=Arial>CCCCCC</span>DDDDD</span></p>

<p style=XXX>EEEE<span class=A>FFFF<span lang=en-us style=Arial>GGGGG</span>HHHHH</span></p>

<p style=XXX>IIIII<span class=A>JJJJJ<span lang=en-us style=Arial>KKKKK</span>DDDDD</span></p>

<p style=XXX>LLLLL<span class=A>MMMM<span lang=en-us style=Arial>NNNNN</span>OOOOO</span></p>

</body>


感觉上代码好像只处理了第一段的最外层的Span标签。 但是结果是第一段的所有span标签都得到了整理。有些迷惑。

论坛徽章:
3
戌狗
日期:2014-09-10 17:07:162015年辞旧岁徽章
日期:2015-03-03 16:54:15wusuopu
日期:2016-06-17 17:43:45
26 [报告]
发表于 2009-02-10 16:09 |只看该作者
原帖由 niaya 于 2009-2-10 16:06 发表


目前我的情况应该算是并列,就是一段一个 段末

这种情况下应该如何应对比较好呢? 每一段属性都差不多。怎么提取能便捷些。

这样的html



AAAABBBBCCCCCCDDDDD

EEEEFFFFGGGGGHHHHH

IIIIIJ ...

跟循环处理<span>一样的方法,循环处理<p ..>。

论坛徽章:
3
戌狗
日期:2014-09-10 17:07:162015年辞旧岁徽章
日期:2015-03-03 16:54:15wusuopu
日期:2016-06-17 17:43:45
27 [报告]
发表于 2009-02-10 16:14 |只看该作者

回复 #24 niaya 的帖子

并列好处理一些。大概像下面那样(没测试)
  1. my $h = HTML::TreeBuilder->new_from_content( decode($encode, $html) );

  2. # 1) 遍历<p>节点
  3. for my $p ($h->look_down(_tag => q{p}) ) {

  4.     my $mainspan;
  5.     for my $span( $h->look_down(_tag => q{span}) ){ #2
  6.         if ( defined $span->attr('lang') ) {
  7.             $span->attr(lang=>undef); #删除lang属性
  8.                 $mainspan = $span;    #用$mainspan记录该span节点
  9.                 last;
  10.         }
  11.     }

  12.     # 3) 把所有span节点的内容直接赋值给,span节点的父节点(即前面找到的$p
  13.     for my $span( $h->look_down(_tag => q{span}) ) {
  14.             $span->replace_with_content($span->content_refs_list);
  15.             }

  16.             # 4) detach掉$p的内容,因为要放在$mainspan里
  17.             my @content = $p->content_list;
  18.             $p->detach_content();

  19.             $mainspan->push_content(@content);

  20.             # 5) 把内容放在$mainspan里
  21.             $p->push_content($mainspan);
  22. }

  23. print encode( $encode, $h->as_HTML('<>&',' ',{}) ), "\n";

  24. $h->delete;
复制代码

论坛徽章:
0
28 [报告]
发表于 2009-02-12 10:17 |只看该作者
关于这段代码,还有最后两个问题。

第一是健壮性问题,并不是每一段都一定有<span face=XXX><span class=XXX><span lang=XXX>这样的TAG。这个时候导致my @content = $p->content_list;这行代码时返回一个空列表。导致程序编译出错。
尝试着向下面这样改,依然提示编译出错。


  1. my $encode = "GBK";
  2. my $h = HTML::TreeBuilder->new_from_content( decode($encode, $s) );
  3.        
  4. for my $p ($h->look_down(_tag => q{p}) ) {
  5.    
  6.     for my $span( $h->look_down(_tag => q{span}) ) {
  7.         if ( defined $span->attr('lang') ) {
  8.             $span->attr(lang=>undef);
  9.             $mainspan = $span;   
  10.               last;  
  11.             } else {
  12.                     $span = "";
  13.                     }
  14.         }
  15.    
  16.     for my $span( $h->look_down(_tag => q{span}) ) {
  17.            
  18.     if ( $span == "" ) {
  19.             last;
  20.             } else {
  21.             $span->replace_with_content($span->content_refs_list);
  22.             
  23.             my @content = $p->content_list;
  24.             $p->detach_content();
  25.             
  26.             $mainspan->push_content(@content);

  27.           $p->push_content($mainspan);
  28.         }
  29.       }   
  30.         }

  31.         $s = encode( $encode, $h->as_HTML('<>&',' ',{}) ), "\n";
复制代码



第二个问题是,目前对于多段的处理还是有问题。只有最后一段的处理是完全正确的。

比如,原始代码:


  1. <body>

  2. <p style='margin-top:0pt;margin-right:0pt;margin-bottom:0pt;margin-left:.0pt; '><span face=Arial><span class=GramE><span class=grame><span lang=EN-US style='font-size:10.0pt; font-family:Arial'><b> AAAAA </b><span face=Arial>BBBBB</span></b><span face=Arial>CCCCC </span><b><span face=Arial> AAAA</span></b><span face=Arial>DDDDD</span><span
  3. face=Arial><span style="mso-spacerun:yes">EEEEE</span></span><span face=Arial>FFFFF</span>
  4. <span face=Arial>GGGGG</span><o:p></o:p></span></span></span></span></p>

  5. <p style='margin-top:0pt;margin-right:0pt;margin-bottom:0pt;margin-left:.0pt; '><span face=Arial><span class=GramE><span class=grame><span lang=EN-US style='font-size:10.0pt; font-family:Arial'><b> AAAAA </b><span face=Arial>BBBBB</span></b><span face=Arial>CCCCC </span><b><span face=Arial> AAAA</span></b><span face=Arial>DDDDD</span><span
  6. face=Arial><span style="mso-spacerun:yes">EEEEE</span></span><span face=Arial>FFFFF</span>
  7. <span face=Arial>GGGGG</span><o:p></o:p></span></span></span></span></p>
  8.        
  9. <p style='margin-top:0pt;margin-right:0pt;margin-bottom:0pt;margin-left:.0pt; '><span face=Arial><span class=GramE><span class=grame><span lang=EN-US style='font-size:10.0pt; font-family:Arial'><b> AAAAA </b><span face=Arial>BBBBB</span></b><span face=Arial>CCCCC </span><b><span face=Arial> AAAA</span></b><span face=Arial>DDDDD</span><span
  10. face=Arial><span style="mso-spacerun:yes">EEEEE</span></span><span face=Arial>FFFFF</span>
  11. <span face=Arial>GGGGG</span><o:p></o:p></span></span></span></span></p>

  12. </body>
复制代码


修正后代码


  1. <body>
  2.    <p style="margin-top:0pt;margin-right:0pt;margin-bottom:0pt;margin-left:.0pt; "><b> AAAAA </b>BBBBBCCCCC <b> AAAA</b>DDDDDEEEEEFFFFF GGGGG</p>
  3.    <p style="margin-top:0pt;margin-right:0pt;margin-bottom:0pt;margin-left:.0pt; "><b> AAAAA </b>BBBBBCCCCC <b> AAAA</b>DDDDDEEEEEFFFFF GGGGG</p>
  4.    <p style="margin-top:0pt;margin-right:0pt;margin-bottom:0pt;margin-left:.0pt; "><span style="font-size:10.0pt; font-family:Arial"><b> AAAAA </b>BBBBBCCCCC <b> AAAA</b>DDDDDEEEEEFFFFF GGGGG</span></p>
  5. </body>
复制代码


前两段的<span style="font-size:10.0pt; font-family:Arial">这个TAG都已经被删掉了。
小弟驽钝,百思不得其解,求赐教。

论坛徽章:
3
戌狗
日期:2014-09-10 17:07:162015年辞旧岁徽章
日期:2015-03-03 16:54:15wusuopu
日期:2016-06-17 17:43:45
29 [报告]
发表于 2009-02-12 10:42 |只看该作者

回复 #27 niaya 的帖子

$span == ""
先不管用""对不对,跟""比较应该用eq

论坛徽章:
3
戌狗
日期:2014-09-10 17:07:162015年辞旧岁徽章
日期:2015-03-03 16:54:15wusuopu
日期:2016-06-17 17:43:45
30 [报告]
发表于 2009-02-12 10:49 |只看该作者

回复 #29 ynchnluiti 的帖子

遍历span时应该用$p->look_down
  1. for my $span( $p->look_down(_tag => q{span}) ) ...
复制代码

不是$h->look_down
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP