CustomFeed::Script for AmazonMP3 ranking

CustomFeed::Script for MixiNewsがうまくいったので、ついでにAmazon.com MP3 Downloads Bestsellers: The most popular items in MP3 Songs. Updated hourly.のランキング100をRSSにするスクリプトを作りました。

今まではDapper: The Data Mapperを使ってスクレイピングRSSにしていたのですが、amazonMP3だけうまく動作しなくなったのでPlaggerを使ってRSS生成するようにしました。

吐き出されたRSSを読み込んでYouTubeAPIに検索かけることでCDTube - カウントダウンチューブの洋楽版ができあがる。

amazonmp3ranking.pl
フィードタイトルに曲名、本文にアーティスト名

#!/usr/bin/perl

use strict;
use Web::Scraper;
use URI;
use utf8;

my $uri = URI->new('http://www.amazon.com/gp/bestsellers/dmusic/digital-music-track/ref=pd_ts_dmusic_nav');

my $scraper = scraper {
	process '//div[2]//div//td[3]', 'lists[]' => scraper { 
		process '//strong/a',
			 'artist' => 'TEXT';
		process '//a[last()-1]',
			 'title' => 'TEXT';
		}
};

my $res = $scraper->scrape($uri);

my $feed = {
	title => 'amazonmp3',
	link => $uri->as_string,
	type => 'amazon',
};

for my $entry (@{ $res->{lists} }){
	push @{$feed->{entries}},{
		title => $entry->{title},
		body  => $entry->{artist},
};
}

use YAML;
binmode STDOUT, ":utf8";
print Dump $feed;

応用記事

  1. P::P::Filter::YouTubeFromTitle (Yusukebe::Tech)
  2. PerlでYouTubeのGData検索をする (Yusukebe::Tech)

YouTubeGdataサブルーチン
一応動いていますので使えるかも

sub search_youtube{
        my ($self,$context,$query) = @_;
        my $url = "http://gdata.youtube.com/feeds/api/videos?vq=" .
           URI::Escape::uri_escape_utf8($query);
        my $feed = XML::Atom::Feed->new(URI->new($url));

           $query = encode('UTF-8', $query) unless $context->conf->{no_decode_utf8};
#   $query =~s/([^\w\/\.\?:=&#])/sprintf("%%%02X", unpack("C", $1))/eg;
           $query =~ tr/\'/+/;
           $query =~ tr/ /+/;
           $context->log( info => 'Getting YouTube search results for ' . $query );

        my @entries = $feed->entries;
	die "" unless $entries[0];
        my $video_id;
        foreach my $link ( $entries[0]->link ) {
            my $href = $link->href;
            if($href =~ m!www.youtube.com/watch\?v=(.*)$!){
                $video_id = $1;
                $context->log(info => "$video_id get!");
                 }
              }
        return $video_id;
}