追記 2017/07/15
C#に書き直した修正版 → https://ptsv.jp/2016/04/20/tweet-image-download-agent/
2015年11月27日・29日 コード修正
コード修正 画像ファイルの正規表現の間違い修正・ちょこっと追加。
コード修正 URL を favorites => likes に変更
2015年11月23日 コード修正
2回目以降のtimelineのURLの決定方法が間違っておりましたので修正しました。ごめんなさい(m_m)
2015年11月17日 コード修正
ログインを行うコードを追加。これにより、ブラウザからクッキーファイルをエクスポートする手間を省くようにした。ログインコードはこれでいいのかどうかわからん。twitterってrails使ってんだっっけ? よくわからんが、適当。
本来はTwitter APIを使わないといけないと思うけど・・・API経由は正直メンドクサイ。勉強する気なし。(m_m)
C#で書き直したプロトタイプをさっき書いたので、これもデバッグが終わり次第また書こっと。
『perlなんかインストールしてねーよ、ボケ!』って方は、C#で書き直した方に ビルドしたやつを置いてます。
今年の2月ぐらいに書いたtwitter画像ダウンロードスクリプトが動かなくなったので修正・修正(^_^;;
2回目以降のタイムライン取得のURLが変更になったみたい?。昼休みにブラウザでアクセスしてデベロッパーツールでちょこっと解析したんですが・・・どのパラメーターで読めばいいのか、いまいち分かんないです。適当です。あくまで、自分用の備忘録なんで、すみません。取れればいいんです(m_m)
twitterにログインするところまで書きなおそうと一瞬思いましたが、また今度にします(・・;
ブラウザでログインしてクッキーエクスポート、twitter.comドメインだけ抜き出して、カレントディレクトリへcookie.txtというファイル名で保存。テキトーですまない。
使い方は下記参考。ログインしたcookie.txtが必要なのは、いいね(旧称:お気に入り)の取得のみ。他人のIDの「いいね」も同様にログインが必要です。この辺よくわからん。自分もしくは他人のIDのタイムラインにログインクッキーは必要ない。です。
#!/usr/bin/perl =pod =head1 ツイッターでのタイムラインから、画像のみダウンロードするスクリプト 使い方 targetに画像を取得したいアカウント名を指定する。 (いいね 画像の場合は type に favo をセット(デフォルト) (※ いいね 取得は自分以外のアカウントでも必ずログインが必要みたいです。) > twitter.pl --username=xxxxx --password=yyyyy --type=favo --target=zzzz (単に任意のアカウントのタイムラインの画像が欲しい場合は type に profileをセット) (TLに流れているリツイートも含めた画像を取得したい場合は、timelineをセット) (※通常公開されているアカウントのタイムラインではusename,passwordは必要ありません。 (※非公開アカウントではフォローを許可されたアカウントのusername/passwordが必要です。) > twitter.pl --type=profile --target=公開アカウント名 ディレクトリ<tmp>に画像が吐き出されます。 =cut use strict; use warnings; use LWP::UserAgent; use Getopt::Long qw/:config no_ignore_case/; my %CONFIG = (username => '', password => '', dir => './tmp', type => 'favo', target => ''); my %TIMELINE = (favo => 'https://twitter.com/%s/likes/timeline', profile => 'https://twitter.com/i/profiles/show/%s/media_timeline', timeline => 'https://twitter.com/i/profiles/show/%s/timeline'); #エージェント my $UserAgent = LWP::UserAgent->new(cookie_jar => {}); &{sub { my @argv = @_; my $result = Getopt::Long::GetOptionsFromArray(\@argv, 'username=s' => \$CONFIG{username}, 'password=s' => \$CONFIG{password}, 'type=s' => \$CONFIG{type}, 'dir=s' => \$CONFIG{dir}, 'target=s' => \$CONFIG{target}); exists $TIMELINE{$CONFIG{type}} or die "invalid type....\n"; $CONFIG{dir} || die "specified output directory...\n"; $CONFIG{target} || die "specified target account name...\n"; mkdir $CONFIG{dir} unless(-e $CONFIG{dir}); &use_lwp_agent; }}(@ARGV); sub use_lwp_agent { my ($param,$result) = ('?include_available_features=1&include_entities=1',''); if($CONFIG{username} && $CONFIG{password}) { my $response = $UserAgent->get('https://twitter.com/login'); $result = $response->decoded_content; $result =~ /<input type="hidden" value="([\d\w]+?)" name="authenticity_token"(?:\s*\/)?>/ or die "can not detect authenticity_token...\n"; my $auth = $1; $response = $UserAgent->post('https://twitter.com/sessions', {'session[username_or_email]' => $CONFIG{username}, 'session[password]' => $CONFIG{password}, 'authenticity_token' => $auth, 'remember_me' => '1', 'redirect_after_login' => '/' }) or die "can not access login page... \n"; $result = $response->decoded_content; die "failed to login...\n" if($result =~ /error/); } my $url = sprintf($TIMELINE{$CONFIG{type}},$CONFIG{target}); do { my $timeline = $url.$param; print "---- getting and parsing\n$timeline ...\n----\n"; $result = &lwp_agent($timeline,'-') || die "can not get timeline. may be wrong url.\n"; $param = &get_images($result,\&lwp_agent); } while( $param ); print "done!\n"; } #タイムラインのJSONデータから画像を取得して、次のタイムラインのパラメータを返す。 sub get_images { my ($json,$agent) = @_; $json =~ s/\\\//\//g; foreach my $url_($json =~ m!https://pbs\.twimg\.com/media/[\w\-]+\.\w{3,4}(?::large)?!g) { if($url_ =~ m/([\w\-]+\.\w{3,4})(:large)?$/) { my $basename = $1; my $filename = "$CONFIG{dir}/$basename"; if($2) { $url_ =~ s/:large/:orig/; } else { $url_ .= ':orig'; } unless(-e $filename) { print "fetching: $url_\n"; &$agent($url_,$filename); print "saved $basename\n"; } } } my @ids = $json =~ m/data-tweet-id=\\\"([0-9]+)/g; my $max_id = @ids > 0 ? pop @ids : ''; return $max_id ? "?max_position=${max_id}&include_available_features=1&include_entities=1" : undef; } #URLを取得して返す。 sub lwp_agent { my ($url,$ofile) = @_; my %options = (); if($ofile ne '-') { if($ofile eq ':src') { if($url =~ /([\w\-\.%]+?\.\w)$/) { $ofile = "$CONFIG{dir}/$1"; } else { goto cleanup; } } return $UserAgent->get($url,':content_file' => $ofile); } cleanup: if(my $response = $UserAgent->get($url)) { return $response->decoded_content; } 0; } __END__