我为这里的长度道歉,但我认为除了描述我的问题之外,还包括我的少量进展是有意义的!
我想从一些有几个表格的 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”之类的条目实际上缺少带有可能显示“-”的条目的数据,我希望将其输出为逗号分隔符而不干预内容。
任何意见,将不胜感激。