使用HTML :: TableExtract提取多行

时间:2013-02-25 20:09:04

标签: perl www-mechanize

我创建了一个脚本,它将从HTML <TR>标记中提取所有Row数据。我的HTML页面上有30个HTML <TR>标记。根据计数,我的代码将获取特定的行数据。假设我需要第5 <tr>...</tr>条中存在的数据,那么我的条件为if(count =5) {(go inside and get that data)}

但我的问题是我需要一次选择一行的数据。假设我需要第5,6和14行的数据。

你能帮我解决一下吗?

$te = new HTML::TableExtract(count => 0 );
$te->parse($content);
# Examine all matching tables
foreach $ts ($te->table_states) {
    #print "Table (", join(',', $ts->coords), "):\n";
    $cnt = 1;
    foreach $row($ts->rows) {
        # print " ---- Printing Row $cnt ----\n";
        $PrintLine= join("\t", @$row);
        @RowData=split(/\t/,$PrintLine);
        $PrintLine =~ s/\r//ig;
        $PrintLine =~ s/\t//ig;
        $cnt = $cnt + 1;
        #   if ($PrintLine =~ /Site ID/ig || $PrintLine =~ /Site name/ig){print " Intrest $PrintLine $cnt =====================\n"};
        if ( $cnt == 14) { 
            $arraycnt = 1;
            my $SiteID="";
            my $SiteName="";
            foreach (@RowData) {
                # print " Array element $arraycnt\n";
                chomp;
                $_ =~ s/\r//ig;
                $_ =~ s/[\xC3\xA1\xC3\xA0\xC3\xA2\xC3\xA3]//ig;
                if ($arraycnt== 17 ) { $SiteID= $_;}
                if ($arraycnt== 39 ) { $SiteName= $_;}
                    $arraycnt = $arraycnt + 1;
            } 
            #$PrintLineFinal = $BridgeCase."\t".$PrintLine;
            $PrintLineFinal = $BridgeCase."\t".$SiteID."\t".$SiteName;
            #print "$PrintLineFinal\n";
            print MYFILE2 "$PrintLineFinal\n";          
            last;
        }       
    }
}

2 个答案:

答案 0 :(得分:0)

一些建议:

始终:

 use strict;
 use warnings;

这会强制您使用my声明变量。 e.g。

foreach my $ts ($te->table_states) {
   my $cnt = 1;

warnings会让您了解最愚蠢的错误。strict通过要求您在某些情况下使用更好的做法来防止错误。

在一些地方,当您浏览数组时,您正在使用自己的计数器变量。你不需要这样做。相反,只需直接获取所需的数组元素即可。例如$array[3]获取第三个元素。

Perl还允许数组切片获得您想要的某些元素。 @array[4,5,13]获取数组的第五,第六和第十四个元素。您可以使用它来处理您想要的行,而不是遍历所有行:

my @rows = $ts->rows;
foreach my $row (@rows[4,5,13]) #process only the 5th, 6th, and 14th rows.
{
    ...
}

这是同一个东西的快捷版,使用匿名数组:

foreach my $row (@{[$ts->rows]}[4,5,13])

此外,您可能希望在代码中的其他位置定义所需的行:

my @wanted_rows = (4,5,13);
...
foreach my $row (@{[$ts->rows]}[@wanted_rows])

这段代码很混乱:

$PrintLine= join("\t", @$row);
@RowData=split(/\t/,$PrintLine);
$PrintLine =~ s/\r//ig;
$PrintLine =~ s/\t//ig;

首先,您要使用制表符加入数组,然后分割刚刚加入的数组以重新获取数组。然后,无论如何都要从行中删除所有制表符。

我建议你摆脱所有代码。只要您需要数组,只需使用@$row,而不是复制它。如果您需要打印数组进行调试(这就是您对$PrintLine所做的一切),您可以直接打印数组:

print @$row;    #print an array, nothing between each element.
print "@$row";  #print an array with spaces between each element.

通过所有这些更改,您的代码将是这样的:

use strict;
use warnings;

my @wanted_rows = (4,5,13);

my $te = new HTML::TableExtract(count => 0);

$te->parse($content);
# Examine all matching tables
foreach my $ts ($te->table_states) {
    foreach my $row (@{[$ts->rows]}[@wanted_rows]) {

        s/[\xC3\xA1\xC3\xA0\xC3\xA2\xC3\xA3\r\n]//ig for (@$row);

        my $SiteID   = $$row[16] // '';  #set to empty strings if not defined.
        my $SiteName = $$row[38] // '';  
        print MYFILE2 $BridgeCase."\t".$SiteID."\t".$SiteName;
    }
}

答案 1 :(得分:0)

您可以像这样访问结果:

foreach $ts ($te->table_states) {
    #you need 14th rows
    #my 14throws = $ts->rows->[13];#starting with zero!
    #17th col from the 14th row
    #my $17colfrom14throws = $ts->rows->[13]->[16];
    my $SiteName = $ts->rows->[13]->[38];
    my $SiteID   = $ts->rows->[13]->[16];
    my $PrintLineFinal = $BridgeCase."\t".$SiteID."\t".$SiteName;
    print MYFILE2 "$PrintLineFinal\n";     
}