AOI-CATの日記

2009-02-03発表会の補足

いまたくらんでること 00:12  いまたくらんでること - AOI-CATの日記 を含むブックマーク

  1. 動画の再生数(マイリスト)をタグに持たせる。これを全動画に対して繰り返す(足していく)。
  2. 足された数字の平均値・中央値などをタグの重みとする。
  • これを使って平均マイリスト重み率を出すと、良作の多いタグが見えてこないだろうか。
  • タグの重みを足して、ある程度期待される再生数より実際の再生数の方が少なければ「埋もれている」と言えないだろうか。
  • また、重みだけ眺めても、おもしろいタグが見えてくるかもしれない。

以上を実験中。今回はアイマスだけでなくボカロでも試してみる予定。

発表会補足 00:12  発表会補足 - AOI-CATの日記 を含むブックマーク

はじめに

補足の内容は技術的な細かいお話です。データ的に細かいお話はやりません。

せっかくなので、いま使用中のコードを使って手順を細かく説明します。

データ取得手順紹介

文字コードと出力
use utf8;
use open ":utf8";
binmode STDOUT, ":utf8";

ソースはutf8で書く。出力も同じ。

use LWP::UserAgent;
use Encode qw/find_encoding from_to encode decode/;
my $ua = LWP::UserAgent->new;
my $res = $ua->get('http://example.com/');
my $content = decode('utf8', $res->content);
# or
$enc_utf8 = find_encoding('utf8');
my $content = $enc_utf8->deocode($res->content);

繰り返し同じ文字コードでdecode/encodeする場合は、find_encodingの処理分、下のコードが早いらしい。

ログイン
my $ua = LWP::UserAgent->new( keep_alive => 1 );
$ua->cookie_jar( {} );
my $res = $ua->post(
	'https://secure.nicovideo.jp/secure/login?site=niconico',
	{ mail =>  "", password => "" }
);

これでログインして、以降の操作をする。

ページ取得

まずはリクエストするURLhttp://www.nicovideo.jp/tag/[エンコードされた検索クエリ]?sort=f&page=[ページ数])を作る。sort=fは新着順。

my $tag = 'アイドルマスター';
{
	use bytes;
	$tag =~ s/([^a-zA-Z0-9_ ])/'%' . unpack('H2', $1)/eg;
	$tag =~ tr/ /+/;
}

これで、エンコードされた検索クエリになる。

URLが決まったらgetして、decodeして、正規表現などで動画IDを抽出すればいい。

my $regex_links = '><a href="watch\/([a-z][a-z]\d+)"><img alt';
my @links = ($content =~ m/$regex_links/smg);

我ながら酷いコードだけど、これでも問題なく抽出できている。

API問い合わせ

http://www.nicovideo.jp/api/getthumbinfo/sm9

といった形でアクセスすると、xmlデータを返してくれます。これをパースするなり何なりして、データをしまいます。

自分は全て正規表現で抜き出してます。モジュールを使うのも面倒だったので。

my ($video_id) = $content =~ m|<video_id>(.*)</video_id>|ms;
# (中略)
my @tag_groups = $content =~ m|(<tags domain=".*?">.*?</tags>)|gms; 

なお以下の方法でxmlのfirst_retrieveと同じ形式の時刻を作れます。

use POSIX qw/strftime/;
my $now = strftime("%Y-%m-%dT%H:%M:%S", localtime()) ."+09:00";
SQLiteの扱い

配布が楽(ファイル一つ)。perlから使うのも楽。

use DBI;
my $db_file = 'nicomas.sqlite';
my $dbh = DBI->connect("dbi:SQLite:dbname=$db_file", "", "",
	{ RaiseError => 1, AutoCommit => 0});
my $sth = $dbh->prepare(
	"INSERT INTO video".
	"(video_id, prefix, title, post_date, length)".
	"VALUES (?,?,?,?,?)"
);

# (中略)

$sth->execute($video_id, $prefix_id, "$title", $first_retrieve, $length);

$sth->finish;
undef $sth;
$dbh->commit;
$dbh->disconnect;

以上こんな感じ。