一旦你获取页面LWP::Simple
,您可以根据需要做什么来选择特定的工具,而不是使用通用的解析器。
在这种情况下,您手上有一张桌子,我建议您HTML::表格提取。有了它,您可以通过多种方式干净地检索表元素,然后处理它们。它可以处理多个表、使用标头、设置解析首选项等等。通常您甚至不必查看实际的 HTML。该模块是一个子类HTML::Parser
。根据我的经验,这是一个非常好的工具。
以下是针对此特定页面和任务的一些基本代码。
use warnings;
use strict;
use LWP::Simple;
use HTML::TableExtract;
my $url = "http://weather.gc.ca/past_conditions/index_e.html?station=yyz";
my $page = get($url) or die "Can't load $url: $!";
my $headers = [ 'Time', 'Temperature', 'Humidex' ];
my $tec = HTML::TableExtract->new(headers => $headers);
$tec->parse($page);
my $fmt = "%6s | %6s | %6s | %8s\n";
printf($fmt, 'Time', 'T-high', 'T-low', 'Humidex');
my ($time, $temp_hi, $temp_low, $hum);
foreach my $rrow ($tec->rows) {
# Skip rows without expected data. Clean up leading/trailing spaces.
next if $rrow->[0] !~ /^\s*\d?\d:\d\d/;
my @row = map { s|^\s*||; s|\s*$||; $_ } @$rrow;
# Process as needed
($time, $hum) = @row[0,2];
($temp_hi, $temp_low) = $row[1] =~ /(\d+) .* \( (\d+\.\d+) \)/xs;
printf($fmt, $time, $temp_hi, $temp_low, $hum);
}
输出的前几行
Time | T-high | T-low | Humidex
16:00 | 29 | 29.2 | 37
15:00 | 27 | 27.2 | 37
14:00 | 26 | 25.6 | 33
...
评论。
The headers
属性为new
使其仅提取这些标题下的列。循环变量是一个参考,到具有行元素的数组。这些元素是单元格中的原始文本。
第一行跳过不具有预期格式的行 - 可能的数字\d?
后面跟着另一个数字,然后:
然后是两位数。这是为了时间,3:00
or 03:00
.
数组引用$rrow
被提取到一个数组中@row
为了清楚起见。
特定列中寻找的元素,@row[0,2]
来时就使用。那个在$row[1]
由正则表达式解析,它捕获一个数字(\d+)
然后用一个分隔的两个数字.
,可能有中间文本(.*
)。这些捕获由正则表达式返回,并分配给其他两个变量。
请参阅模块的文档,如果需要,请参阅参考教程佩尔勒夫图特以及正则表达式佩尔雷图特。另一个有用的页面是 Data Structures Cookbookperldsc。其他介绍参见教程。它们通常包含指向更具体文档的链接。