使用perl剥离HTML标记

时间:2010-07-05 01:38:16

标签: html perl parsing tags

什么是在perl中剥离HTML标记的最简单方法。我正在使用正则表达式解析来自URL的HTML,该URL工作得很好但是如何删除HTML标记呢?

以下是我如何提取HTML

 #!/usr/bin/perl -w
use strict;
use warnings;
use LWP::Simple;
my $now_string = localtime;

my $html = get("http://www.spc.noaa.gov/climo/reports/last3hours.html")
    or die "Could not fetch NWS page.";
$html =~ s/<script.*?<\'/script>/sg;
$html =~ s/<.+?>//sg;
$html =~ m{(Hail Reports.*)Wind Reports}s || die;
my @hail = $1;

5 个答案:

答案 0 :(得分:10)

尝试回答误入歧途的问题


问题


进入正则表达式HTML是一个坏习惯,因为有太多的规则和方法来绕过它们,这可能最终打开你的代码到黑客技术。虽然您现在可能对简单的事情有合理的需求,但重用代码并忘记为什么重用代码是个坏主意,尤其是当您不添加# This code is NOT secure and should not be used to parse HTML anywhere else!!!或{{1}等注释时}

需要大量正则表达式规则的HTML差异示例:

# Christina Alguilera writes songs based on this code!!!

列表继续,这仅适用于格式良好的HTML。其他一些问题包括:

  1. HTML元素未正确关闭(例如<div>...</div> <div style="blah"> <div style="background:url(../div)"> <div style=".." class='noticesinglequote'> )或根本没有关闭
  2. 拼写错误(例如<div><span></div></span>
  3. 旨在破坏脚本的HTML设计
  4. 其他问题:评论,空白,字符集等
  5. 解决方案


    您可能已接受答案,但应查看XML::ParserHTML::TreeBuilder

    您可能更感兴趣的是深入了解所需文档的某些部分(例如,<dvi>..</div>中的所有内容或其中的某个<body>,而不是剥离部分HTML文档。这就是为什么你最有可能想要上述模块之一提供的东西。更不用说,解析器可用于尽力删除所有HTML元素并仅返回text / CData。

答案 1 :(得分:7)

如上所述,不要使用正则表达式。有太多例外。

可以提供帮助的一个CPAN模块是HTML::Strip

use HTML::Strip;

my $hs         = HTML::Strip->new();
my $clean_text = $hs->parse( $raw_html );
$hs->eof;

值得学习CPAN上可用的内容并使用它。从长远来看,它将为您节省大量工作。

答案 2 :(得分:5)

查看HTML::Restrict模块,该模块允许您删除或限制允许的HTML标记。剥离所有HTML标记的最小示例:

use HTML::Restrict;

my $hr = HTML::Restrict->new();
my $processed = $hr->process('<b>i am bold</b>'); # returns 'i am bold'

我建议远离HTML :: Strip,因为it breaks utf8 encoding

答案 3 :(得分:0)

还有一个很好的Perl模块HTML :: Scrubber。

 #!/usr/bin/perl
 use warnings; 
 use strict;
 use HTML::Scrubber;
 my $file = shift or die "need a file $!\n";

 my $html;
 open (FH,"< $file");
 read( FH, $html, -s FH );
 close FH;
 #print "$html\n";

  my $scrubber = HTML::Scrubber->new;
  $scrubber->default(1); ## default to allow HTML

   #$scrubber->script(0); ## no script
   #$scrubber->style(0); ## no style
   # OR
   $scrubber->deny(qw[script style]);

   my $clean_html = $scrubber->scrub($html);

  open (OH, '>', $file.'.scrubbed.html');
  print OH $clean_html;
  close OH;
  exit;

答案 4 :(得分:-1)

如果您只想删除HTML标记:

s/<script.*?<\/script>//sg
s/<.+?>//sg

这将(大部分时间)删除脚本标记及其内容以及所有其他HTML标记。您也可以使用正则表达式安全地删除<body>标记之前的所有内容。

对于比这更复杂的任何,正则表达式是一个合适的工具,你真的需要用实际的HTML解析器解析HTML然后操作那就是删除标签。