mixiページが始まってから、また、mixiを使うようになりました。
…少しだけですが。
で、コミュニティのトピックを見ていた時に、画像を一つ一つクリックして見るのが面倒になったので、どうにかならないかと思って書きました。

WWW::Mixi::Scraperを使いました。
WWW::Mixi::Scraper::Plugin::ViewBBSを見てみたところ、トピックのサブジェクトの画像は取得しているのですが、コメントの画像は取得していないので、取得するように改造しました。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
--- WWW-Mixi-Scraper-0.33/lib/WWW/Mixi/Scraper/Plugin/ViewBBS.pm	2011-09-20 09:43:10.000000000 +0900
+++ lib/WWW/Mixi/Scraper/Plugin/ViewBBS.pm 2011-09-18 00:07:30.000000000 +0900
@@ -53,7 +53,9 @@
name => 'TEXT';
process 'dd',
description => $self->html_or_text;
- result qw( link name description );
+ process 'dd>div.communityPhoto>table>tr>td',
+ 'images[]' => $scraper{images};
+ result qw( link name description images );
};
$scraper{list} = scraper {
@@ -77,6 +79,7 @@
# incompatible with WWW::Mixi to let comment links
# look more 'permanent' to make plagger/rss readers happier
+ $comment->{images} = WWW::Mixi::Scraper::Plugin::_images( $comment->{images} ) if defined $comment->{images};
$comment->{name_link} = _uri( $comment->{link} );
$comment->{link} = $stash->{link}
? _uri( $stash->{link} . '#' . $comment->{subject} )

その上で、画像に直接アクセスするように、Pluginを2つほど追加しました。
lib/WWW/Mixi/Plugin/ShowBBSPicture.pm

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package WWW::Mixi::Scraper::Plugin::ShowBBSPicture;
use strict;
use warnings;
use WWW::Mixi::Scraper::Plugin;
use WWW::Mixi::Scraper::Utils qw( _uri );
validator {qw(
id is_number
comm_id is_number
number is_number
)};
sub scrape {
my ($self, $html) = @_;
my %scraper;
$scraper{picture} = scraper {
process 'img',
link => '@src';
result qw( link );
};
# bbs picture
my $stash;
$stash->{link} = _uri($scraper{picture}->scrape(\$html));
return $stash;
}
1;

lib/WWW/Mixi/Plugin/ShowBBSCommentPicture.pm

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package WWW::Mixi::Scraper::Plugin::ShowBBSCommentPicture;
use strict;
use warnings;
use WWW::Mixi::Scraper::Plugin;
use WWW::Mixi::Scraper::Utils qw( _uri );
validator {qw(
bbs_id is_number
id is_number
comm_id is_number
number is_number
)};
sub scrape {
my ($self, $html) = @_;
my %scraper;
$scraper{picture} = scraper {
process 'img',
link => '@src';
result qw( link );
};
# bbs picture
my $stash;
$stash->{link} = _uri($scraper{picture}->scrape(\$html));
return $stash;
}
1;

これらを踏まえた上で、以下が本体です。
./get_mixi_photo.pl http://mixi.jp/view_bbs.pl?id=38584544&comm_id=6896&page=all
という感じに使います。
Config::Pitについては「パスワード設定をコードに書かない(Config::Pit) - モダンなPerl入門 - モダンなPerl入門」を参考にしてアカウント情報を入力してください。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#!/usr/bin/env perl
#utf8
use utf8;
use 5.12.1;
use WWW::Mixi::Scraper;
use lib 'lib';
use Digest::MD5 qw( md5_hex );
use Encode;
use Config::Pit;
my $config = pit_get(
'nqounet@mixi.jp',
require => {
email => 'username@domain.com',
password => 'password',
},
);
use Log::Handler;
my $log = Log::Handler->new(
file => {
filename => 'log/app.log',
utf8 => 1,
maxlevel => 'info',# 'debug',
timeformat => '%Y/%m/%d %H:%M:%S',
message_layout => '[%T][%L] %m (%C)',
},
);
my $mixi = WWW::Mixi::Scraper->new(
mode => 'TEXT',
%{$config},
);
my $topic = shift(@ARGV);
$log->die('Usage: ./get_mixi_photo.pl topicURL') unless $topic;
my @list = $mixi->parse( $topic );
$log->dump( debug => \@list );
# トピックのタイトル
my $dir = md5_hex( Encode::encode_utf8( $list[0]{subject} ) );
mkdir $dir;
open my $fh, '>:utf8', qq{$dir/info.txt} or $log->die( qq{Can not open $dir/info.txt.} );
print $fh $list[0]{subject};
close $fh;
# トピックのトップ画像
for my $item ( @{$list[0]{images}} ) {
$log->dump( debug => $item->{link} );
my @urls = $mixi->parse( $item->{link} );
for my $url ( @urls ) {
save_url_image( $url, $dir );
}
}
# 各コメントの画像
for my $comment ( @{$list[0]{comments}} ) {
for my $item ( @{$comment->{images}} ) {
$log->dump( debug => $item->{link} );
my @urls = $mixi->parse( $item->{link} );
for my $url ( @urls ) {
save_url_image( $url, $dir );
}
}
}
# 保存一式
sub save_url_image {
my ($url, $dir) = @_;
my $link = $url->{link}->as_string;
$log->dump( debug => $url->{link} );
my ($ext) = $link =~ /(\.[a-zA-Z]+)$/ms;
$log->dump( debug => $ext );
$ext = '.jpg' unless $ext;
my $filename = md5_hex( $link ) . $ext;
return if -f qq{$dir/$filename};
my $content = $mixi->{mech}->get_content( $url->{link} );
$log->dump( debug => $content );
open my $fh, ">:raw", qq{$dir/$filename} or $log->die( qq{Can not open $dir/$filename.} );
print $fh $content;
close $fh;
}