Web::Scraperでmuxtapeのtape情報の一覧を取得する

muxtapeで注目されているtapeを聞いてみたいなぁと思ってfansの数を引っこ抜いてみました。それだけだとつまらないので、おまけに曲情報なども取得するようにしてみています。

#!/usr/bin/env perl
use strict;
use warnings;
use Web::Scraper;
use URI;
use Perl6::Say;
use Path::Class;
use YAML::Syck;
$YAML::Syck::ImplicitUnicode = 1;

main();

sub main {
    say "collecting tapes ...";

    my $tapes = parse_tape_lists_page();
    generate_tape_lists($tapes);

    say "Done! See muxtape.yaml ;)";
}

sub parse_tape_lists_page {

    my $uri     = URI->new("http://muxtape.com/");
    my $scraper = scraper {
        process 'ul.featured a', 'accounts[]' => {
            name => 'TEXT',
            link => '@href',
        };
    };
    my $result = $scraper->scrape($uri);
    my $tapes =[];

    say "fetching " . @{ $result->{accounts} } . " tapes";
    foreach my $account ( @{ $result->{accounts} } ) {
        my $tape = parse_tape_page( $account->{link} );
        push @{$tapes} , $tape;
    }
    $tapes;
}

sub parse_tape_page {
    my $url = shift;
    say "fetching tape: $url";
    my $scraper = scraper {
        process 'div.flag h1', 'title', 'TEXT';
        process 'div.flag h2', 'description', 'TEXT';
        process 'a.drawer_control', 'fans', sub { 
            $_->as_text =~ m/([0-9]+) fans/; 
            if( $1 ) { return $1; } else { "0"; }
        };
        process 'li.stripe', 'songs[]' => scraper {
              process 'span.artist', 'artist','TEXT';
              process 'span.title', 'title','TEXT';
        };
    };
    my $result = $scraper->scrape($url);
    return $result;
}

sub generate_tape_lists {
    my $tapes = shift;
    DumpFile("muxtape.yaml",$tapes);
}

__END__

# WWW::Muxtape::Scraperって形にしといてもよかったかもなぁ。