【问题标题】:How can I extract XML of a website and save in a file using Perl's LWP?如何使用 Perl 的 LWP 提取网站的 XML 并保存在文件中?
【发布时间】:2010-09-18 06:39:32
【问题描述】:

如何从网站 (http://tv.yahoo.com/listings) 中提取信息,然后从中创建 XML 文件?我想保存它以便稍后解析并使用 JavaScript 显示信息?

我对 Perl 很陌生,我不知道该怎么做。

【问题讨论】:

    标签: javascript xml perl extract lwp


    【解决方案1】:

    当然。最简单的方法是 Web::Scraper 模块。它的作用是让您定义由

    组成的刮板对象
    1. 散列键名,
    2. 定位感兴趣元素的 XPath 表达式,
    3. 以及从中提取数据位的代码。

    Scraper 对象采用 URL 并返回提取数据的哈希值。如有必要,每个键的提取器代码本身可以是另一个刮板对象,以便您可以定义如何刮取重复的复合页面元素:提供 XPath 以在外部刮板中查找复合元素,然后提供更多 XPath 来拉取在内部刮刀中取出其各个位。结果会自动成为一个嵌套的数据结构。

    简而言之,您可以非常优雅地将整个页面的数据提取到 Perl 数据结构中。这样做时,XPath + Perl 的全部功能可用于任何页面。由于该页面是使用 HTML::TreeBuilder 解析的,因此它的 tagoup 有多糟糕并不重要。生成的爬虫脚本比基于正则表达式的爬虫更容易维护,并且更能容忍微小的标记变化。

    坏消息:到目前为止,它的文档几乎不存在,因此您必须通过谷歌搜索类似 [miyagawa web::scraper] 的内容才能找到模块作者发布的示例脚本。

    【讨论】:

    • 另见 [datenzoo.de/pub/gpw2008/web-scraper/… 是我关于 Web::Scraper 的德语演讲。自动翻译:[66.196.80.202/babelfish/…
    • 你真的要推荐这种beta模块吗?
    • 测试版,真的吗?它是 LWP、HTML::TreeBuilder 和 HTML::Selector::XPath 组合的粘合剂,所有经过实战考验的生产质量模块。但是,如果您喜欢编写样板文件,那就适合自己……
    • 我还没有尝试过,所以也许我草草下结论。但作者指出“此模块处于其测试版质量。API 是从 SCRAPI 中窃取的,但将来可能会更改”
    【解决方案2】:

    虽然一般LWP::SimpleWWW::MechanizeHTML::Tree 是从网页中提取数据的好方法,但在这种特殊情况下(电视节目表)有一种更简单的方法:

    XMLTV 与来自Schedules Direct 的数据一起使用。收取少量费用(20 美元/年),但也有优势:

    1. 解析代码已经为您编写好了(只是use XMLTV;)。
    2. 您不会违反雅虎的服务条款。
    3. 您不必与 Yahoo 积极尝试破坏您的脚本打交道。 (他们不喜欢自动脚本拉下电视节目表;请参阅 #2。)

    【讨论】:

      【解决方案3】:

      如果您想将信息传递给 Javascript,请使用 Javascript 对象表示法 (JSON) 而不是 XML。有很多 Perl 库,例如 JSON::Any,可以为您处理。

      【讨论】:

        【解决方案4】:

        tv.yahoo.com 不是很语义化,也不是很容易抓取!它们可能是更好的替代品或提要?

        使用 pQuery 我可以快速获取时间和节目......

        use pQuery;
        pQuery( 'http://tv.yahoo.com/listings' )
            ->find( '.show' )->each(
                sub {
                    my $n = shift;
                    my $pQ = pQuery( $_ ); 
                    say $pQ->text;
                }
            );
        
          # => 4:00pm - 6:30pm Local Programming
        

        要了解更多细节,你可以试试这个......

        use pQuery;
        my @tv_progs;
        pQuery( 'http://tv.yahoo.com/listings' )
            ->find( 'li div strong' )->each(
                sub {
                    my $n = shift;
                    my $pQ = pQuery( $_ ); 
                    $tv_progs[ $n ]->{ time } = $pQ->text;
                }
            )
            ->end
            ->find( '.showTitle' )->each( 
                sub {
                    my $n = shift;
                    my $pQ = pQuery( $_ ); 
                    $tv_progs[ $n ]->{ name } = $pQ->text;
                }
            );
        
        for my $prog ( @tv_progs ) {
            say $prog->{name} . " @ " . $prog->{time};
        }
        
           # => Local Programming @ 4:00pm - 6:30pm
        

        并获得频道....

        use pQuery;
        pQuery( 'http://tv.yahoo.com/listings' )
        ->find( '.chhdr a' )->each(
            sub {
                my $n = shift;
                my $pQ = pQuery( $_ ); 
                say $pQ->text;
            }
        );
        
          # => ABC
        

        但是,将反向频道与节目信息匹配需要一些工作;-)

        【讨论】:

          猜你喜欢
          • 2012-11-24
          • 1970-01-01
          • 2012-06-10
          • 2011-02-12
          • 2014-01-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-10-15
          相关资源
          最近更新 更多