2

我为这里的长度道歉,但我认为除了描述我的问题之外,还包括我的少量进展是有意义的!

我想从一些有几个表格的 html 页面中提取数据。在 使用的方案中,关键表HTML::TableExtract位于depth=>0, count=>2。我在这里的代码示例中使用的特定页面是:http ://www.myschool.edu.au/ResultsInNumbers/Index/61209/ConingsbyStateSchool/46701/2011 。它在您输入的开头有一个烦人的 Search-CAPTCHA,例如“Coningsby”。忽略周围的 HTML,表格结构基本上如下块所示。

<table class="results-in-numbers">
  <thead>
    <tr>
      <td class="year-column"></td>
      <th colspan="2" scope="col">Reading</th>
      <th colspan="2" scope="col">Writing</th>
    </tr>
  </thead>
  <tbody>
    <tr class="selected-school-row">
      <th scope="row" rowspan="3">Year 3</th>
      <td colspan="2">
        <span class="avg">449</span>
        <span class="err">404 - 494</span>
      </td>
      <td colspan="2">
        <span class="avg">395</span>
        <span class="err">359 - 431</span>
      </td>
    </tr>
    <tr class="color-row">
      <td><img src="" alt ="" /></td>
      <td><img src="" alt =""/></td>
      <td><img src="" alt ="" /></td>
      <td><img src="" alt =""/></td>
    </tr>
    <tr class="sim-all-row">
      <td>
        <span class="sim">SIM</span>
        <span class="sim-avg">411</span>
        <span class="err">402 - 420</span>
      </td>
      <td>
         <span class="all">ALL</span>
         <span class="sim-avg">416</span>
      </td>
      <td>
         <span class="sim">SIM</span>
        <span class="sim-avg">410</span>
        <span class="err">402 - 418</span>
      </td>
      <td>
         <span class="all">ALL</span>
         <span class="sim-avg">416</span>
      </td>
    </tr>
  </tbody>
</table>

我以几种方式简化了表格。首先,顶部实际上有五个整体标题,而不仅仅是阅读和写作,但每个已删除副本的布局与阅读和写作的布局完全相同。其次,我只包括了与“第 3 年”相对应的三组行,如行中所示 <th scope="row" rowspan="3">Year 3</th>。对我的问题来说,重要的可能是我不知道会有多少这样的行跨度。在示例页面上有 3 个,但有时只有 1 个,最多 4 个。

我想组织输出中的数据,以便以逗号分隔的形式与每年的相关数字(如单行的“第 3 年”),所以我需要能够检测到年份和然后还捕获接下来的两个表行,以便表示单个rowspan="3"块的单行输出将读取

3,449,404,494,395,359,431,411,402,420,416,410,402,418,416

开头的 3 代表“第 3 年”。我真的不知道处理三行的rowspan-ed块的明智方法,所以目前我的代码只生成如下行(包括中间不需要的空白行):

#!/usr/bin/perl
use HTML::TableExtract;
use constant false => 0;
use constant true  => 1;
foreach $html_file (@ARGV) {
  print "$html_file \n";
  $te = HTML::TableExtract->new( gridmap => false, subtables => true );
  $te->parse_file($html_file);

  # I don't know how many rows there are in the table, so I don't
  # know how to count through them in triplets
  foreach my $r ( $te->table(0,2)->rows() ) {
      foreach my $col ( @$r ) {
        # remove unwanted white space that results from the multiple
        # spans within each <td> </td> block
        $col =~ s/[\h\v]+/ /g;
        # remove leading whitespace
        $col =~ s/^ *//;
        # remove trailing whitespace
        $col =~ s/ *$//;
        print $col, " ";
      }
      print "\n";
    }
  print "\n";
}

GotSchools/61/61998-61209-ConingsbyStateSchool-46701-2011-n
 Reading  Writing
Year 3 449 404 - 494  395 359 - 431

 SIM 411 402 - 420 ALL 416 SIM 410 402 - 418 ALL 416

我将不胜感激有关如何进行的建议。例如,我是否应该使用正则表达式来检测行首的年份,以及删除 SIM 和 ALL 字样?此外,在某些页面中,此处显示为“402 - 418”之类的条目实际上缺少带有可能显示“-”的条目的数据,我希望将其输出为逗号分隔符而不干预内容。

任何意见,将不胜感激。

4

0 回答 0