我试图从EnviroCanada天气页面中提取以下内容。
我试图按照以下方式获得每小时。
时间|大腿| Tlow |湿度
7:00 | 23 | 22.9 | 30
提取的HTML页面:
require(['module name'])
到目前为止代码:
require
我完全迷失在这里
答案 0 :(得分:4)
使用LWP::Simple
获取页面后,您可以根据需要使用它来选择特定工具,而不是使用常规解析器。
在这种情况下,您手上有一张桌子,我建议HTML::TableExtract。有了它,您可以通过多种方式干净地检索表格元素,然后处理它们。它可以使用多个表,使用标题,设置解析首选项等。通常,您甚至不必查看实际的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 ...
评论
headers
的{{1}}属性使其仅在这些标题下提取列。循环变量是引用,是带有行元素的数组。元素是单元格中的原始文本。
第一行会跳过不具有预期格式的行 - 可能的数字new
后跟另一个数字,然后是\d?
,然后是两位数。这是时间:
或3:00
。
为清晰起见,arrayref 03:00
被提取到数组$rrow
中。
特定列中的搜索元素@row
在它们到来时使用。 @row[0,2]
中的一个由正则表达式解析,该正则表达式捕获一个数字$row[1]
,然后是两个以(\d+)
分隔的数字,并带有可能的插入文本(.
)。这些捕获由正则表达式返回,并分配给其他两个变量。
请参阅模块的文档,如果需要,请参阅参考perlreftut和正则表达式perlretut的教程。另一个有用的页面是Data Structures Cookbook perldsc。有关其他介绍,请参阅Tutorials。它们通常包含指向更具体文档的链接。