【问题标题】:Extract information from HTML using wget and Perl使用 wget 和 Perl 从 HTML 中提取信息
【发布时间】:2019-05-09 18:50:54
【问题描述】:

我正在尝试编写一个类似于电视指南的 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;

【问题讨论】:

  • 这是一个很大的 HTML 页面,因此使用正则表达式可能不是好方法...您应该考虑使用真正的 HTML 解析器
  • 用正则表达式解析 HTML 充其量只是运气。正则表达式并不是真正适合这项工作的工具。检查类似于 HTML::TokenParser 的内容。还可以使用 LWP::Simple 消除 wget 并将数据直接拉入您的脚本

标签: linux perl debian


【解决方案1】:

第一件事:使用正则表达式处理 HTML 是个坏主意。他们原则上不适合工作,在实践中遇到困难。这方面已经写了很多了。

我知道您“只是”想要获取标题,但您手头有一个成熟的 HTML 文档。问题会不断蔓延,事情会变得更糟,而且不会有尽头。

相反,有许多模块可以为您解析各种类型的内容。至于表格,你需要什么,HTML::TableExtract 尤其是一个最优秀的工具。

HTML 文档也可以通过一些好的模块在您的脚本中轻松检索。我在下面使用LWP::Simple,但请查看完整的LWP::UserAgentMojo::UserAgent,例如。

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

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;            # collapse multiple spaces, newlines
        $_                       # return it
    } @$rowref;

    say join ' | ', @row;
 }

注意 undef、空格和换行符清理语句,其中每行的 arrayref 被“解包”到一个数组中。还有其他方法可以做到这一点,但我将其保留为在您必须使用正则表达式进入 HTML 细节时展示它是如何进行的。

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

前几行,为了可读性也被截断

全部 |晚上 11:00(播出)|晚上 11:30 | 12:00 上午 | 12:30 上午 |凌晨1:00 ... WPBT2HD 2.1 |凯尔特女人:古代土地 11:00 pm | | | |退休保险... WPBT2-2 2.2 | Globe Trekker 德里和阿格拉10:30 pm |莉迪亚的厨房... ...

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-23
      • 2021-09-23
      • 2011-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多