用HTML提取几行:: TableExtract

问题描述:

我制作了一个脚本,它将从HTML <TR>标签中提取所有行数据。我的HTML页面上有30个HTML <TR>标签。基于计数,我的代码将获取特定的行数据。假设我需要第5个<tr>...</tr>中的数据,那么我的条件是if(count =5) {(go inside and get that data)}用HTML提取几行:: TableExtract

但是我的问题在于我需要一次选择一行数据。假设我需要第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; 
     }  
    } 
} 
+0

得益于正确缩进代码。 – 2013-02-25 20:11:46

几点建议:

始终:

use strict; 
use warnings; 

这将迫使你与my来声明变量。例如

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

你可以访问的结果是这样的:

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";  
}