免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 4883 | 回复: 10
打印 上一主题 下一主题

用Perl实现对Html可变标签整理的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-02-16 10:50 |只看该作者 |倒序浏览
20可用积分
之前麻烦过大家一次,这次还需要大家继续帮忙。
对一个用Word编辑过的html页面进行htmlTAG整理。

html的body部如下

$html

  1. <body>
  2. <p style='margin-top:0pt;margin-right:0pt;margin-bottom:0pt;margin-left:.0pt; '>
  3. <span lang=JA style='font-size:10.0pt; font-family:Arial'>aaaaa<span face=Arial><span class=GramE>
  4. <span class=grame><span lang=EN-US style='font-size:9.0pt; font-family:Arial'><b> AAAAA </b>
  5. <span style=Arial><span face=Arial>BBBBB</span></b><span face=Arial>CCCCC </span><b>
  6. <span face=Arial> DDDDD</span></b><span face=Arial>EEEEE</span><span face=Arial>
  7. <span style="mso-spacerun:yes">FFFFF</span></span><span face=Arial>GGGGG</span>
  8. <span face=Arial>HHHHH</span><o:p></o:p></span></span></span></span></span></span></p>
  9.        
  10. <p style='margin-top:0in;margin-right:0in;margin-bottom:0in;margin-left:.2in;
  11. margin-bottom:.0001pt;'><span face=Arial><span class=GramE><span
  12. class=grame><span style='font-size:9.0pt;line-height:150%;font-family:Arial'>OOOOO
  13. <b><span face=Arial>PPPPP</span></b><span face=Arial> IIIII </span><b><span
  14. face=Arial>JJJJJ</span></b><span face=Arial> KKKKK</span><span
  15. face=Arial><span style="mso-spacerun:yes">&nbsp;</span></span><span face=Arial>LLLLL</span>
  16. <span face=Arial>MMMMM</span><o:p></o:p></span></span></span></span></p>

  17. </body>
复制代码


利用下面这段Perl代码整理

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

  4.     for my $p ($h->look_down(_tag => q{p}) ) {

  5.         for my $span( $h->look_down(_tag => q{span}) ) {
  6.             if ( defined $span->attr('lang') ) {
  7.                 $span->attr(lang=>undef);
  8.                 $mainspan = $span;
  9.                 last;
  10.             } #else {
  11. #$mainspan = $span;
  12.       #last;
  13. #}
  14.         }

  15.         for my $span( $p->look_down(_tag => q{span}) ) {
  16.             $span->replace_with_content($span->content_refs_list);
  17.         }

  18.         my @content = $p->content_list;

  19.         if (@content) {
  20.             $p->detach_content();
  21.             $mainspan->push_content(@content);

  22.             $p->push_content($mainspan);
  23.         }
  24.     }

  25.     $s = encode( $encode, $h->as_HTML('<>&',' ',{}) ) . "\n";

  26.     print $html;

  27.     $h->delete;

  28. }
复制代码


处理之后的代码如下。
$html

  1. <body>
  2.    <p style="margin-top:0pt;margin-right:0pt;margin-bottom:0pt;margin-left:.0pt; ">
  3.    </p>
  4.    <p style="margin-top:0in;margin-right:0in;margin-bottom:0in;margin-left:.2in; margin-bottom:.0001pt;"><span style="font-size:9.0pt; font-family:Arial">aaaaa <b> AAAAA </b> BBBBBCCCCC <b>  DDDDD</b>EEEEE FFFFFGGGGG HHHHHOOOOO <b>PPPPP</b> IIIII <b>JJJJJ</b> KKKKK&nbsp;LLLLL MMMMM</span></p>
  5. </body>
复制代码


里面的内容整理得有问题。
请问如何修正代码可以使下面的要求实现。

删除<span lang=XXX> <span face=XXX><span class=XXX>及对应的</span>标签
将<span lang=XXX style=XXX>这样的标签转换成<span style=XXX>
注意:<span style=XXX>的标签不删。

[ 本帖最后由 niaya 于 2009-2-16 10:51 编辑 ]

论坛徽章:
3
戌狗
日期:2014-09-10 17:07:162015年辞旧岁徽章
日期:2015-03-03 16:54:15wusuopu
日期:2016-06-17 17:43:45
2 [报告]
发表于 2009-02-16 10:50 |只看该作者
  1. {
  2.         my $h = HTML::TreeBuilder->new_from_content( decode($encode, $html) );

  3.         for my $span( $h->look_down(_tag => q{span}) ) {
  4.                 $span->attr(lang=>undef) if ( defined $span->attr('lang') );

  5.                 $span->replace_with_content($span->content_refs_list) if
  6.                         ( not defined $span->attr('style') );
  7.         }

  8.         $s = encode( $encode, $h->as_HTML('<>&',' ',{}) ) . "\n";

  9.         print $s;

  10.         $h->delete;
  11. }
复制代码

<html>
<head>
</head>
<body>
  <p style="margin-top:0pt;margin-right:0pt;margin-bottom:0pt;margin-left:.0pt; "><span style="font-size:10.0pt; font-family:Arial">aaaaa <span style="font-size:9.0pt; font-family:Arial"><b> AAAAA </b> <span style="Arial">BBBBBCCCCC <b>  DDDDD</b>EEEEE <span style="mso-spacerun:yes">FFFFF</span>GGGGG HHHHH</span></span></span></p>
  <p style="margin-top:0in;margin-right:0in;margin-bottom:0in;margin-left:.2in;
margin-bottom:.0001pt;"><span style="font-size:9.0pt;line-height:150%;font-family:Arial">OOOOO <b>PPPPP</b> IIIII <b>JJJJJ</b> KKKKK<span style="mso-spacerun:yes">&nbsp;</span>LLLLL MMMMM</span></p>
</body>
</html>

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

回复 #2 ynchnluiti 的帖子

结果是楼主要的吗?

论坛徽章:
0
4 [报告]
发表于 2009-02-16 14:47 |只看该作者
非常谢谢ynchnluiti的帮助 这段代码已经基本解决了这个问题。

但是目前还有2个小问题需要解决。

1 代码中单引号和双引号的问题:
原始代码     <p style='margin-top:0pt;margin-right:0pt;margin-bottom:0pt;margin-left:.0pt; '>
转换后代码  <p style="margin-top:0pt;margin-right:0pt;margin-bottom:0pt;margin-left:.0pt; ">

这里的符号发生了变化,在英文网页中看没有任何问题,但是日文版网页中就会看到一些标签失效的问题。
这里我在想是不是$h->as_HTML('<>&',' ',{}) 这个地方的问题。
能不能修改一下让这个单引号不要变成双引号呢?

2 对于一些特殊字符  诸如 √ ∫ № μ ① ② ③ 这样的符号都没有被正确识别,语言Code已经被正确导入了的话。
是否还要追加一些设定呢?

论坛徽章:
3
戌狗
日期:2014-09-10 17:07:162015年辞旧岁徽章
日期:2015-03-03 16:54:15wusuopu
日期:2016-06-17 17:43:45
5 [报告]
发表于 2009-02-16 19:44 |只看该作者
原帖由 niaya 于 2009-2-16 14:47 发表
非常谢谢ynchnluiti的帮助 这段代码已经基本解决了这个问题。

但是目前还有2个小问题需要解决。

1 代码中单引号和双引号的问题:
原始代码     
转换后代码  

这里的符号发生了变化,在英文网页中看 ...

1 暂时没找到dump标签属性用单引号的设置。不过日文里,html的属性应该也可以用双引号吧
2 脚本的编码,浏览软件(浏览器,编辑器等)的编码也要一致。

论坛徽章:
0
6 [报告]
发表于 2009-02-17 10:29 |只看该作者
原帖由 ynchnluiti 于 2009-2-16 19:44 发表

1 暂时没找到dump标签属性用单引号的设置。不过日文里,html的属性应该也可以用双引号吧
2 脚本的编码,浏览软件(浏览器,编辑器等)的编码也要一致。


是这样,因为我说的这个问题只是我要实现功能的一部分。
还有其他的处理是基于原来的这部分代码的。
如果说改变了这样的TAG信息,大部分的内容我都要写两次判断,这样比较麻烦。

能不能不使用这个TreeBuilder直接完成这个处理?
比如说,把整个html拼成一个字符串,对这个字符串进行处理。
(每一段落<p>对于<span>进行堆栈操作的话可行吗?)

现在的确是不希望代码的变动太大。如果不用这个TreeBuilder的话,上面这两个问题都不会发生。

论坛徽章:
3
戌狗
日期:2014-09-10 17:07:162015年辞旧岁徽章
日期:2015-03-03 16:54:15wusuopu
日期:2016-06-17 17:43:45
7 [报告]
发表于 2009-02-17 13:50 |只看该作者
原帖由 niaya 于 2009-2-17 10:29 发表
能不能不使用这个TreeBuilder直接完成这个处理?
比如说,把整个html拼成一个字符串,对这个字符串进行处理。
(每一段落<p>对于<span>进行堆栈操作的话可行吗?)

复杂的html不好处理。

论坛徽章:
0
8 [报告]
发表于 2009-02-18 11:02 |只看该作者
原帖由 ynchnluiti 于 2009-2-17 13:50 发表

复杂的html不好处理。


那我把我的需求补充一下吧。
刚才看了下,可以实现对某些TAG的删除。

比如说我现在要对<head></head>这对标签进行整理。
将其间所有除了<title></title>这个标签以外的所有子节点全部删除。

例如

  1. <head>
  2. <meta XXXXX>
  3. <meta XXXXX>
  4. <title>AAAAA</title>
  5. <style=XXXXX>
  6. <style=XXXXX>
  7. .
  8. .
  9. .
  10. <XXXXXX>
  11. </head>
复制代码


整理为

  1. <head>
  2. <title>AAAAA</title>
  3. </head>
复制代码

这样

最好用TreeBuilder这类Html的模块实现。
应该用(content_list())吗?

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

1 暂时没找到dump标签属性用单引号的设置。不过日文里,html的属性应该也可以用双引号吧
2 脚本的编码,浏览软件(浏览器,编辑器等)的编码也要一致。


这个问题英文Html的确是没有什么问题,但是在日文上面涉及到双引号和单引号的区别问题。

如下所示:


  1. #!/usr/bin/perl -w

  2. use warnings;
  3. use strict;

  4. use Encode;
  5. use HTML::Entities;
  6. use HTML::TreeBuilder;

  7. my $encode = 'shift_jis';

  8. my $html = <<'__HTML__';
  9. <html>

  10. <head>
  11. <title>TestForJP</title>
  12. </head>

  13. <body lang=JA>

  14. <p style='margin-top:0mm;margin-right:0mm;margin-bottom:0mm;margin-left:28.4pt;
  15. margin-bottom:.0001pt;'><span lang=EN-US
  16. style='font-size:10.0pt;font-family:"MS 明朝"'>AAAAA</span><span
  17. style='font-size:10.0pt;font-family:"MS 明朝"'>BBBBB<span
  18. lang=EN-US>CCCCC</span>DDDDD。<span lang=EN-US><br>
  19. EEEEE</span>FFFF<span lang=EN-US><br style='mso-special-character:line-break'>
  20. <![if !supportLineBreakNewLine]><br style='mso-special-character:line-break'>
  21. <![endif]><o:p></o:p></span></span></p>

  22. </body>

  23. </html>
  24. __HTML__

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

  27.     my $p = $h->look_down(_tag => q{p});
  28.    
  29.     for my $span( $h->look_down(_tag => q{span}) ) {
  30.                 $span->attr(lang=>undef) if ( defined $span->attr('lang') );

  31.                 $span->replace_with_content($span->content_refs_list) if
  32.                         ( not defined $span->attr('style') );
  33.         }


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

  35.     $h->delete;
  36. }
  37. __END__
  38. <html>
  39. <head>
  40.   <title>TestForJP</title>
  41. </head>
  42. <body lang="JA">
  43.   <p style="margin-top:0mm;margin-right:0mm;margin-bottom:0mm;margin-left:28.4pt
  44. ;
  45. margin-bottom:.0001pt;"><span style="font-si
  46. ze:10.0pt;font-family:"MS 明朝"">AAAAA</span><span style="fon
  47. t-size:10.0pt;font-family:"MS 明朝"">BBBBBCCCCCDDDDD。<br />
  48. EEEEEFFFF<br style="mso-special-character:line-break" />
  49.     <br style="mso-special-character:line-break" /></span></p>
  50. </body>
  51. </html>
复制代码


第一遍的结果是正确的。
但是如果把第一遍的这个结果再整理一次的话。
整理之后的Html代码就会像下面这个样子。


<html>
<head>
  <title>TestForJP</title>
</head>
<body lang="JA">
  <p style="margin-top:0mm;margin-right:0mm;margin-bottom:0mm;margin-left:28.4pt
;margin-bottom:.0001pt;"><span style="font-si
ze:10.0pt;font-family:" 明朝""="明朝""" ms="MS">AAAAA</span
><span style="fon
t-size:10.0pt;font-family:" 明朝""="明朝""" ms="MS">BBBBBCC
CCCDDDDD。<br /> EEEEEFFFF<br style="mso-special-character:line-break" />
    <br style="mso-special-character:line-break" /></span></p>
</body>
</html>

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

回复 #8 niaya 的帖子

原帖由 niaya 于 2009-2-18 11:02 发表
应该用(content_list())吗?

可以用content_list。应该也有别的方法。
  1. my $html= << '__HTML__';
  2. <head>
  3. <meta XXXXX>
  4. <meta XXXXX>
  5. <title>AAAAA</title>
  6. <style=XXXXX>
  7. <style=XXXXX>
  8. <XXXXXX>
  9. </head>
  10. <body>

  11. </body>
  12. __HTML__

  13. {
  14.     my $h = HTML::TreeBuilder->new_from_content( $html );

  15.     for my $head ($h->look_down(_tag => q{head}) ) {
  16.             foreach my $item ($head->content_list) {
  17.                     $item->delete if not $item->tag() eq 'title';
  18.             }
  19.     }

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

  21.     $h->delete;

  22. }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP