2011-09-30 18 views
4

因此,我有一個報告工具,吐出HTML文件中的作業調度統計信息,並且我正在使用Perl來使用這些數據。我不知道如何通過HTML表格。獲取​​值與Perl

我知道如何使用

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

用jQuery做到這一點,但我不知道如何做到這一點同樣的邏輯用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> 

回答

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}; 
    } 
    } 
} 
+4

使用正則表達式的html是所有邪惡的根源。 http://www.codinghorror.com/blog/2009/11/parsing-html-the-cthulhu-way.html – CountMurphy

+2

你*可以*使用正則表達式,但是...是一個可怕的,非常糟糕的主意。 – aus

+2

@CountMurphy我愛[那個答案](http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags)。這是昇華的藝術。 – stivlo

3

這裏我使用了HTML解析器::是有點冗長,但保證工作。我正在使用鑽石操作員,因此您可以將其用作過濾器。如果你調用這個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; 
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 ::查詢文檔來獲取如何使用它一個更好的主意---上面是很難的最漂亮的例子。

+0

哦,嘿,有光澤的東西!我以前不知道[HTML :: Query](https://metacpan.org/module/HTML::Query)。不過,提問者可能更容易使用'text'或'file'參數而不是'tree'參數。 'tree'需要一個[HTML :: Element](https://metacpan.org/module/HTML::Element)對象。 –

+0

@BrianWisti不錯,它安裝乾淨,這應該是被接受的答案。 araqnid是否可以在源代碼中添加缺少的部分?所以這個例子將是完整的:使用HTML :: Query;使用HTML :: TreeBuilder;我的$ docName =「test.html」; my $ doc = HTML :: TreeBuilder-> new; $ doc-> parse_file($ docName); – stivlo

+0

這可能比我的解決方案更好。特別是,如果你不能得到HTML :: TableContentParser來安裝。這是相當過時。 – aus

2

Perl CPAN模塊HTML :: TreeBuilder。

我廣泛使用它來解析大量的HTML文檔。

這個概念是你得到一個HTML :: Element(根節點的例子)。 從它,你可以尋找其他的節點: - > CONTENT_LIST()

  • 獲取父節點用 -

    • 讓孩子的列表與節點>父()

    免責聲明:下面的代碼沒有經過測試,但它是這個想法。

    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(); 
    } 
    

    如果你的表是比這更復雜,你可以先找到表元素,然後 遍歷每個TR兒童,併爲每個TR孩子,迭代TD元素...

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

  • +0

    我假設'$ content'是HTML文件。原諒我,我的Perl知識很小,但是我的'$ content'聲明聲明是什麼? (即'my $ content ='? –