3


1

Perlを使用してQuakeLiveプレーヤープロファイルを確実に解析するにはどうすればよいですか?

現在、QuakeLive Webサイトからデータを収集するPerlスクリプトに取り組んでいます。 一連のデータを取得できなくなるまで、すべてがうまくいきました。

私はそのために正規表現を使用していましたが、それらはお気に入りのアリーナ、武器、ゲームの種類を除いてすべてのために動作します。 さらに処理するために、これらの3つの要素の名前を$ 1で取得する必要があります。

お気に入りの画像まで正規表現を試しましたが、成功しませんでした。 使用する場合は、スクリプトで既にWWW

Mechanizeを使用しています。

この問題は、それらの要素がある段落のクラス名に関連していると思いますが、前のものはクラスレスでした。

サンプルプロファイルhttp://www.quakelive.com/profile/summary/martianbuddy[HERE]を見つけることができます。

ページの前の部分では、次のようなコードを使用して機能したことに注意してください。

$content =~ /Wins:<\/b> (.*?)
/;
$wins = $1;
print "Wins: $wins\n";

2 Answer


7


差し迫った問題は、あなたが持っていることです:

                Arena: Campgrounds

つまり、* Arena *などのお気に入りの値の後に ``はありません。 これを行う正しい方法は、適切なHTMLパーサーを使用することです。 脆弱な解決策は、パターンを調整することです(未テスト):

my ($favarena) = $content =~ m{Arena: ([^<]+)};

それはすべてを次の ``の `<`まで置くべきです

「$ favarena」で。 ここで、すべてのアリーナがスペースのない単一の単語である場合、

my ($favarena) = $content =~ m{Arena: (\S+)};

後で空白を削除する手間が省けます。

このような正規表現ベースのソリューションは、ソース内のコメントアウトされたスニペットなどの単純なものにだまされるのは簡単です。 たとえば、ソースを次のように変更する場合:

                Arena: Campgrounds

HTMLパーサーを使用したソリューションではできない場合、スクリプトはトラブルになります。

HTML::TokeParser::Simpleを使用した例:

#!/usr/bin/perl

use strict; use warnings;

use HTML::TokeParser::Simple;

my $p = HTML::TokeParser::Simple->new( 'martianbuddy.html' );

while ( my $tag = $p->get_tag('p') ) {
    next unless $tag->is_start_tag;
    next unless defined (my $class = $tag->get_attr('class'));
    next unless grep { /^prf_faves\z/ } split ' ', $class;

    my $fav = $p->get_tag('b');
    my $type = $p->get_text('/b');
    my $value = $p->get_text('/p');
    $value =~ s/\s+\z//;

    print "$type = $value\n";
}

出力:

Arena:  Campgrounds
Game Type:  Clan Arena
Weapon:  Rocket Launcher
そして、http://search.cpan.org/perldoc/HTML%3a%3aTreeBuilder [HTML

TreeBuilder]を使用した例を次に示します。

#!/usr/bin/perl

use strict; use warnings;

use HTML::TreeBuilder;
use YAML;

my $tree = HTML::TreeBuilder->new;
$tree->parse_file('martianbuddy.html');

my @p = $tree->look_down(_tag => 'p', sub {
        return unless defined (my $class = $_[0]->attr('class'));
        return unless grep { /^prf_faves\z/ } split ' ', $class;
        return 1;
    }
);

for my $p ( @p ) {
    my $text = $p->as_text;
    $text =~ s/^\s+//;
    my ($type, $value) = split ': ', $text;
    print "$type: $value\n";
}

出力:

Arena: Campgrounds
Game Type: Clan Arena
Weapon: Rocket Launcher
ドキュメントが完全なドキュメントではなくHTMLフラグメントであることを考えると、http://search.cpan.org/perldoc/HTML%3a%3aParser [HTML

Parser]に基づくモジュールではなく、より成功します。整形式のXMLドキュメントを操作することを期待します。


5


この特定のタスクに正規表現を使用するのは理想的ではありません。 変更される可能性のあるものが多すぎて、HTMLページの固有の構造を利用していない。 代わりにhttp://p3rl.org/HTML%3a%3aTreeBuilder [`HTML

TreeBuilder`]のようなものを使用することを検討しましたか? 「weaponsという名前のテーブルの3番目のテーブルセルの値を取得してください」などと言うことができます。