3

Webサイト( http://tv.yahoo.com/listings )から情報を抽出し、そこからXMLファイルを作成するにはどうすればよいですか?後で解析してJavaScriptを使用して情報を表示するために保存したいですか?

私はPerlにまったく慣れていないので、その方法がわかりません。

4

4 に答える 4

11

もちろん。最も簡単な方法は、Web::Scraperモジュールです。それは、以下で構成されるスクレーパーオブジェクトを定義できるようにすることです。

  1. ハッシュキー名、
  2. 対象の要素を見つけるXPath式、
  3. そしてそれらからデータのビットを抽出するためのコード。

スクレーパーオブジェクトはURLを受け取り、抽出されたデータのハッシュを返します。各キーのエクストラクタコードは、必要に応じてそれ自体を別のスクレーパーオブジェクトにすることができるため、繰り返される複合ページ要素をスクレイプする方法を定義できます。外部スクレーパーで複合要素を見つけるためのXPathを提供し、プルするXPathをさらに提供します。内側のスクレーパーで個々のビットを取り出します。その結果、自動的にネストされたデータ構造になります。

つまり、ページ全体からPerlデータ構造に非常にエレガントにデータを吸い込むことができます。そうすることで、XPath+Perlの全機能をどのページに対しても使用できるようになります。ページはHTML::TreeBuilderで解析されるため、tagsoupがどれほど厄介であるかは関係ありません。結果として得られるスクレーパースクリプトは、正規表現ベースのスクレーパーよりも保守がはるかに簡単で、マイナーなマークアップのバリエーションに対してはるかに耐性があります。

悪いニュース:まだ、そのドキュメントはほとんど存在しないので、モジュールの作成者によって投稿されたサンプルスクリプトを見つけるには、 [ miyagawa web::scraper ]のようなものをグーグルで検索する必要があります。

于 2008-10-21T07:59:42.707 に答える
3

一般に、LWP::SimpleまたはWWW::MechanizeHTML::Treeは Web ページからデータを抽出する良い方法ですが、この特定のケース (TV リスト) では、はるかに簡単な方法があります:

Schedules DirectからのデータでXMLTVを使用します。少額の料金 (20 米ドル/年) がかかりますが、次の利点があります。

  1. 解析コードは既に作成されています (単にuse XMLTV;)。
  2. Yahoo の利用規約に違反することはありません。
  3. スクリプトを破ろうとする Yahoo に積極的に対処する必要はありません。(彼らは自動化されたスクリプトがテレビのリストを引き出すのを好みません。#2 を参照してください。)
于 2008-10-21T16:53:33.703 に答える
1

情報をJavascriptに渡したい場合は、XMLの代わりにJavascript Object Notation(JSON)を使用してください。JSON :: Anyなど、それを処理できるPerlライブラリはたくさんあります。

于 2008-10-21T17:27:54.773 に答える
1

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

ただし、バックチャネルをプログラム情報に一致させるには少し作業が必要です;-)

于 2008-10-21T21:58:24.103 に答える