使用Perl获取值

时间:2011-09-30 15:36:30

标签: perl parsing

所以我有一个报告工具,它在HTML文件中吐出作业调度统计信息,我希望使用Perl来使用这些数据。我不知道如何逐步浏览HTML表格。

我知道如何使用

使用jQuery
$.find('<tr>').each(function(){
  variable = $(this).find('<td>').text
});

但我不知道如何用Perl做同样的逻辑。我该怎么办?下面是HTML输出的示例。每个表行包括三个相同的统计信息:对象名称,状态和返回代码。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<HTML>
<HEAD>
<meta name="GENERATOR" content="UC4 Reporting Tool V8.00A">
<Title></Title>
<style type="text/css">
th,td {
font-family: arial;
font-size: 0.8em;
}

th {
background: rgb(77,148,255);
color: white;
}

td {
border: 1px solid rgb(208,213,217);
}  

table {
border: 1px solid grey; 
background: white;
}

body {
background: rgb(208,213,217);
}
</style>
</HEAD>
<BODY>
<table>
<tr>
  <th>Object name</th>
  <th>Status</th>
  <th>Return code</th>
</tr>
<tr>
  <td>JOBS.UNIX.S_SITEVIEW.WF_M_SITEVIEW_CHK_FACILITIES_REGISTRY</td>
  <td>ENDED_OK - ended normally</td>
  <td>0</td>
</tr>
<tr>
  <td>JOBS.UNIX.ADMIN.INFA_CHK_REP_SERVICE</td>
  <td>ENDED_OK - ended normally</td>
  <td>0</td>
</tr>
<tr>
  <td>JOBS.UNIX.S_SITEVIEW.WF_M_SITEVIEW_CHK_FACILITIES_REGISTRY</td>
  <td>ENDED_OK - ended normally</td>
  <td>0</td>
</tr>

5 个答案:

答案 0 :(得分:11)

HTML::Query模块是HTML解析器的包装器,它提供了jQuery用户熟悉的查询界面。所以你可以写点像

use HTML::Query qw(Query);
my $docName = "test.html";
my $doc = Query(file => $docName);

for my $tr ($doc->query("td")) {
  for my $td (Query($tr)->query("td")) {
    # $td is now an HTML::Element object for the td element
    print $td->as_text, "\n";
  }
}

阅读HTML :: Query文档以更好地了解如何使用它 - 上面几乎不是最漂亮的例子。

答案 1 :(得分:9)

您可以使用RegExp,但Perl已经为此特定任务构建了模块。查看HTML::TableContentParser

您可能会这样做:

use HTML::TableContentParser;

$tcp = HTML::TableContentParser->new;
$tables = $tcp->parse($HTML);

foreach $table (@$tables) {
  foreach $row (@{ $tables->{rows} }) {
    foreach $col (@{ $row->{cols} }) {
      # each <td>
      $data = $col->{data};
    }
  }
}

答案 2 :(得分:3)

这里我使用HTML :: Parser,有点冗长,但保证可以正常工作。我正在使用钻石操作员,因此您可以将其用作过滤器。如果你调用这个Perl源extractTd,可以通过以下几种方式调用它。

$ extractTd test.html

$ extractTd < test.html

将同时工作,输出将继续标准输出,您可以将其重定向到文件。

#!/usr/bin/perl -w

use strict;

package ExtractTd;
use 5.010;
use base "HTML::Parser";

my $td_flag = 0;

sub start {
    my ($self, $tag, $attr, $attrseq, $origtext) = @_; 
    if ($tag =~ /^td$/i) {
        $td_flag = 1;
    }   
}

sub end {
    my ($self, $tag, $origtext) = @_; 
    if ($tag =~ /^td$/i) {
        $td_flag = 0;
    }   
}

sub text {
    my ($self, $text) = @_; 
    if ($td_flag) {
        say $text;
    }   
}

my $extractTd = new ExtractTd;
while (<>) {
    $extractTd->parse($_);
}
$extractTd->eof;

答案 3 :(得分:2)

您是否尝试过查看cpan的HTML库?这似乎做你想要的 http://search.cpan.org/~msisk/HTML-TableExtract-2.11/lib/HTML/TableExtract.pm

此处还有一整页不同的HTML相关库供您使用 http://search.cpan.org/search?m=all&q=html+&s=1&n=100

答案 4 :(得分:2)

Perl CPAN模块HTML :: TreeBuilder。

我广泛使用它来解析许多HTML文档。

这个概念是你得到一个HTML :: Element(例子中的根节点)。 从中,您可以查找其他节点:

  • 使用 - &gt; content_list()
  • 获取子节点列表
  • 使用 - &gt; parent()
  • 获取父节点

免责声明:以下代码尚未经过测试,但这是理念。

my $root = HTML::TreeBuilder->new;
$root->utf8_mode(1);
$root->parse($content);
$root->eof();
# This gets you an HTML::Element, of the root document
$root->elementify();

my @td = $root->look_down("_tag", "td");
foreach my $td_elem (@td)
{
    printf "-> %s\n", $td_elem->as_trimmed_text();
}

如果你的表比这个更复杂,你可以先找到TABLE元素, 然后迭代每个TR子节点,对于每个TR子节点,迭代TD元素......

http://metacpan.org/pod/HTML::TreeBuilder