2011-06-14 50 views
2

我试图提取一些信息HTML使用Perl。我发现了TreeBuilder和Element和Parser,我应该使用哪一个? 我将如何提取下面一行的名称和值? 此外,这是嵌入在一个HTML结构中,真正的目标是我想要的字段的唯一方法是列“目录数量”的值。 或者我应该只对整个html做一个正则表达式?Perl解析html树buidler或元素或解析器

<table cellspacing="0"> 
    <tbody><tr><td class="black">Number of directories</td><td class="black">:</td><td class="black">&nbsp;80</td></tr> 
     <tr><td class="black">Number&nbsp;of&nbsp;monitored&nbsp;source&nbsp;files</td><td class="black">:</td><td class="black">&nbsp;425</td></tr> 
     <tr><td class="black">Number of functions</td><td class="black">:</td><td class="black">&nbsp;6245</td></tr> 
     <tr><td class="black">Number&nbsp;of&nbsp;source&nbsp;lines</td><td class="black">:</td><td class="black">&nbsp;3245</td></tr> 
     <tr><td class="black">Number&nbsp;of&nbsp;measurement&nbsp;points</td><td class="black">:</td><td class="black">&nbsp;2457</td></tr> 
     <tr><td class="red">TER</td><td class="red">:</td><td class="red">&nbsp;<strong>12%</strong>&nbsp;(decision)</td></tr> 
    </tbody></table> 
+1

制作该HTML的人无法理解CSS的用途:class ='red''的确如此。太糟糕了,因为具有良好结构CSS的代码更容易处理。 – daotoad 2011-06-14 02:02:40

回答

0

有几个步骤。

  1. 使用HTML :: TreeBuilder的构造函数之一来解析HTML。
  2. 通过调用elementify将HTML :: TreeBuilder对象根目录转换为HTML :: Element。
  3. 了解您的HTML结构,您可以告诉HTML::Element::look_down()如何找到您感兴趣的位。您可以指定几乎任何可以想象的形式的条件。
  4. 使用HTML :: Element :: look_down(),content_list(),left(),right()和相关方法遍历感兴趣的区域并提取数据。 请勿使用traverse() - 这是一个坏主意。
  5. 将您收集的数据传递给首先要求的任何系统。

下面是一些代码:

my $blarg = <<'END_HTML'; 
<table cellspacing="0"> 
    <tbody><tr><td class="black">Number of directories</td><td class="black">:</td><td class="black">&nbsp;80</td></tr> 
     <tr><td class="black">Number&nbsp;of&nbsp;monitored&nbsp;source&nbsp;files</td><td class="black">:</td><td class="black">&nbsp;425</td></tr> 
     <tr><td class="black">Number of functions</td><td class="black">:</td><td class="black">&nbsp;6245</td></tr> 
     <tr><td class="black">Number&nbsp;of&nbsp;source&nbsp;lines</td><td class="black">:</td><td class="black">&nbsp;3245</td></tr> 
     <tr><td class="black">Number&nbsp;of&nbsp;measurement&nbsp;points</td><td class="black">:</td><td class="black">&nbsp;2457</td></tr> 
     <tr><td class="red">TER</td><td class="red">:</td><td class="red">&nbsp;<strong>12%</strong>&nbsp;(decision)</td></tr> 
    </tbody></table> 
END_HTML 

# Use any of the constructors to get your base object. See the pod. 
my $tree = HTML::TreeBuilder->new_from_content($blarg); 

$tree->elementify; # Make it just a plain HTML::Element object. 

# Iterate over a list of rows: look_down and related functions provide powerful ways to find matching elements. Read the pod for more details. 
my %crud_from_table; 
for my $row ($tree->look_down(_tag => 'tr')) { 
    my ($key, $value) = map $_->as_text, $row->content_list; # assumes two td per row. 
    $crud_from_table{$key} = $value; 
} 

最重要的部分在于理解和能够描述到look_down()如何找到你想要的信息。有时你可以通过匹配一个id来放大它。其他时候,你必须查找带有表格的“foo”类的第三个div。这也是最难的部分,我可以帮助你至少。你只需要尝试一下。

祝你好运。

+0

非常感谢你的帮助,一个问题我的输出超级讨厌,为什么不是as_text只给我没有html的字符串? $ VAR1 ='Numberáofásourceálines'; $ VAR2 ='á23182'; $ VAR5 ='Coverageáview'; $ VAR6 ='áAsáinstrumented'; $ VAR9 ='Thresholdápercent'; $ VAR10 ='á80á%'; $ VAR11 ='目录数量'; – user391986 2011-06-14 17:22:46

+0

@ user391986,它可能是非破坏性的空间造成你的痛苦。改用' - > as_trimmed_text'。 – daotoad 2011-06-14 19:40:48

+0

我最终做了$ testValue =〜s/\ x {a0} // g;那不好吗?这是我做转储时显示的价值。 – user391986 2011-06-14 23:37:02

1

如果您需要从HTML表格中提取数据,然后

use HTML::TableExtract; 

将是一个不错的选择。

+1

不幸的是,HTML :: TableExtract是面向带有顶部标题而不是左侧的表格(就像这张表一样)。 – cjm 2011-06-17 02:29:03