使用wget和Perl从HTML提取信息

时间:2018-12-08 02:58:49

标签: linux perl debian

我正在尝试编写一个Perl脚本,该脚本的工作方式类似于电视指南,该指南显示了某些频道(例如Fox(7.1 WSVNH)和ABC(10.1 WPLGH))正在播放的当前节目。

我正在尝试实现的输出如下所示:

7.1 - Hell's Kitchen

10.1 - 20/20

... and so on

(频道号和当前节目标题)

这是我要从中提取HTML的网站: https://nocable.org/tv-listings/2f46-miami-fl

这是我用来执行脚本的命令:

wget -O - website | ./script.pl

这是我正在处理的一些代码(注意:由于我仍在学习Perl,因此我试图在Perl中坚持使用正则表达式进行模式匹配):

#!/usr/bin/perl
while ( <> ) {
    @htmlstring = m/wplgh(.*?)br/i
}
print @htmlstring;

我能够提取html块,但不能提取我想要的。我正在尝试提取节目标题。另外,我一直认为从HTML中提取节目标题后最好将其存储在哈希中。

%channel; 
$channel{'7.1'} = $showtitle;
$channel{'10.1'} = $showtitle;

2 个答案:

答案 0 :(得分:4)

第一件事:使用正则表达式处理HTML是一个坏主意。他们原则上不足以胜任工作,而在实践中却遇到麻烦。对此已经写了很多。

我了解到您“仅”希望选择标题,但是您手上有一份完整的HTML文档。问题将不断蔓延,情况将变得更糟,而且这将没有止境。

相反,有许多模块可以为您解析各种类型的内容。对于表格,您需要的HTML::TableExtract特别是一种非常出色的工具。

也可以通过许多好的模块轻松地在脚本中检索HTML文档。我在下面使用LWP::Simple,但例如看到完整的LWP::UserAgentMojo框架。

为简单起见,我获取文档中的第一个表(恰好是正确的表),并且仅对演示进行基本处理。我希望您可以从那里拿走。

use warnings;
use strict;
use feature 'say';

use LWP::Simple;
use HTML::TableExtract;

use open qw(:encoding(UTF-8) :std);

my $url = 'https://nocable.org/tv-listings/2f46-miami-fl';
my $page = get($url) or die "Can't load $url: $!";

my $tec = HTML::TableExtract->new();
$tec->parse($page);

foreach my $rowref ($tec->rows) 
{
    next if not @$rowref;

    # Clean up undefined/whitespace/newlines, often found in HTML
    my @row = map { 
        $_ = '' if not defined;  # keep undefined fields for formatting
        s/^\s*|\s*$//g;          #/ leading and trailing whitespace
        s/\s+|\n/ /g;            # multiple spaces, newlines
        $_                       # return it
    } @$rowref;

    say join ' | ', @row;
 }

请注意undef,空格和换行符清洁语句,其中每行的arrayref被“解包”为数组。还有其他方法可以做到这一点,但是我一无所知,以展示一旦必须使用regex来了解HTML详细信息时的过程。

如果要格式化表格并对齐其元素以进行打印,我会将未定义的元素更改为空字符串。我在元素之间添加了|,以便于查看。请根据您的需求进行调整。

前几行,也出于可读性而被截断

All | 11:00 pm (ON AIR) | 11:30 pm | 12:00 am | 12:30 am | 1:00 am       ...
WPBT2HD 2.1 | Celtic Woman: Ancient Land 11:00 pm |  |  |  | Retire Safe ...
WPBT2-2 2.2 | Globe Trekker Delhi & Agra10:30 pm | Lidia's Kitchen       ... 
...

答案 1 :(得分:0)

为什么要重新发明轮子?使用XMLTV,它可能已经支持您的程序信息源。如果不是,为什么不使用框架和contribute a new grabber for your source

查看其他抓取器,例如使用HTML::TreeBuilder将HTML解析为DOM。在DOM上搜索信息要容易得多,并且在HTML的某些部分发生更改时不容易中断信息。