RubyでFlickrの画像をまとめてダウンロード・バックアップしておく
FlickrからのクリスマスプレゼントでProアカウントが復活してたのがこの3月で期限切れになります(した)。新生Flickrはどうなるか?と期待してたのですが、やっぱりなんだか重くていまどきのサービスとしてはいかがなものか、という気持ちが拭い切れない一方で500pxほどに敷居が高くなくてやっぱり楽しい場所ですね。
Proアカウントはオリジナルサイズのファイルにアクセスできるので、この際、全部ダウンロードしておこうと思い、またまた不慣れなプログラミングに挑戦。泥縄式なため、参考になるかどうか。。。しかし、すぐに忘れるので自分のための備忘録もかねて。
なお、記事を書くのが遅くなりすぎてしまい、クリスマスプレゼントのProアカウントはexpireしてしまってると思いますが、書きかけた記事ですのでアップしておきます。
目次
RubyのFlickrawをインストール
sudo gem install flickraw
FlickrでAPIキーとかトークンとかをもらう流れ
これがややこしいです。
- ブラウザでAPIキーとシェアドシークレットを取得
- Rubyスクリプトで認証用URLを取得
- ブラウザで認証用URLにアクセスして認証用コードを取得
- Rubyスクリプトでアクセストークンとアクセスシークレットを取得
ブラウザでAPIキーとシェアドシークレットを取得
Flickr Servicesで「非商用」なので「APPLY FOR A NON-COMMERCIAL KEY」をクリック。
すると、KeyとSecretという文字列が帰ってきます。
下の方の掲載しているサンプルスクリプト中の
1 2 |
FlickRaw.api_key="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" FlickRaw.shared_secret="xxxxxxxxxxxxxxxx" |
は、ここで取得したキーとシークレットを使います。
Rubyスクリプトで認証用URLを取得
次に認証用URLを取得するのですが、これには次のRubyスクリプトをコンソールで実行させます。
auth.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
require 'flickraw' FlickRaw.api_key="さっき表示されたKey" FlickRaw.shared_secret="同じくSecret" token = flickr.get_request_token auth_url = flickr.get_authorize_url(token['oauth_token'], :perms => 'delete') puts "このURLをブラウザで開いて認証プロセスを完了させてください : #{auth_url}" puts "認証完了後、ブラウザに表示された数字を含む文字列を下にペーストしてください" verify = gets.strip begin flickr.get_access_token(token['oauth_token'], token['oauth_token_secret'], verify) login = flickr.test.login puts "認証完了 ユーザ名-> #{login.username} token-> #{flickr.access_token} secret-> #{flickr.access_secret}" rescue FlickRaw::FailedResponse => e puts "認証失敗 : #{e.msg}" end |
1 2 3 4 5 |
ruby auth.rb Open this url in your process to complete the authication process : http://www.flickr.com/services/oauth/authorize?oauth_token=xxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxx&perms=delete Copy here the number given when you complete the process. |
と返ってきます(下に続く)。こちらの画面はこのままにしておいて、次の工程です。
ブラウザで認証用URLにアクセスして認証用コードを取得
スクリプトから表示されたURL(http://〜deleteまで)をコピーし、ブラウザで開きますにアクセスすると次のような画面へと遷移します。
OK, I’LL AUTHORIZE ITをクリックすると、数字が返ってきます。
Rubyスクリプトでアクセストークンとアクセスシークレットを取得
この数字を先ほどのコンソール画面ターミナルにペーストしてエンター。
1 |
You are now authenticated as ユーザ名 with token xxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxx and secret xxxxxxxxxxxxxxxx |
これでようやく、トークンとシークレットも取得できました。
下の画像取得スクリプト中の
1 2 |
flickr.access_token = "xxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxx" flickr.access_secret = "xxxxxxxxxxxxxxxx" |
は、ここで取得したトークンとシークレットとなります。
Ruby+FlickRawで画像を取得
user_idはアカウント情報(http://www.flickr.com/account)でYour buddy iconの画像のURLに含まれている、http://l.yimg.com/g/images/buddyicon.gif#xxxxxxxx@Nxxの「xxxxxxxx@Nxx」の部分です。
base_dirは保存先ディレクトリ、url_size = ‘url_o’はオリジナルサイズのURLです。
save_file()はhttp://brly.net/blog/2012/03を参考にさせていただきました。
flickr.photosets.getListだけですと、セットに所属しないファイルのURLを取得できないので、flickr.photos.getNotInSetを使ってセットに入れていないのも取得しました。
なお、タイムアウトなどエラー処理を一切してませんので各自工夫してください(というか自分ではできなかったのと、意外にもエラーもなくサクサクと落とせました)。
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 |
#!/usr/local/bin/ruby # -*- coding: utf-8 -*- FlickrawOptions = { :lazyload => true, :timeout => 2 } require 'flickraw-cached' require 'open-uri' require 'fileutils' FlickRaw.api_key="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" FlickRaw.shared_secret="xxxxxxxxxxxxxxxx" flickr.access_token = "xxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxx" flickr.access_secret = "xxxxxxxxxxxxxxxx" user_id = "xxxxxxxx@xxx" base_dir = "/home/hoge/hoge/" url_size = 'url_o' #urlとディレクトリを指定しファイルを保存 #ディレクトリの存在をチェックし、なければ作成する def save_file(url,dir) FileUtils.mkdir_p(dir) unless File.exist?(dir) open(dir + File.basename(url), 'wb') do |file| open(url) do |data| file.write(data.read) end end end #user_idの所有するset内のオリジナルサイズの写真をbase_dirに保存する #ディレクトリ名に不適な文字をアンダースコアで置き換える def fetch_photos_of_sets(user_id, base_dir, url_size) set_list = flickr.photosets.getList :user_id => user_id set_list.each do |photo_set| dir_save = base_dir + photo_set.title.gsub(/[?"\\\<>*|]/,"_") + '/' photo_list = flickr.photosets.getPhotos :photoset_id => photo_set.id, :extras => url_size photo_list.photo.each do |photo| photo_url = photo.url_o p photo_url save_file(photo_url, dir_save) end # sleep 1 end end #ログインIDにおけるセットに所属していない写真をダウンロード #保存ディレクトリはbase_dir下のnot_in_set/に決め打ち def fetch_photos_not_in_set(user_id, base_dir, url_size) list = flickr.photos.getNotInSet(:extras => url_size) list.photo.each do |photo| dir_save = base_dir + 'not_in_set/' p photo.url_o save_file(photo.url_o, dir_save) end end #main begin fetch_photos_of_sets(user_id, base_dir, url_size) fetch_photos_not_in_set(user_id, base_dir, url_size) end |
Comment
久々に使ってみたら、エラーでダウンロードできません。
重宝してるので、よかったら更新お願いします。
RubyFlickRaw.rb:37:in
block (2 levels) in fetch_photos_of_sets': undefined method
url_o’ for # (NoMethodError)from C:/RubyFlickRaw.rb:36:in
each'
block in fetch_photos_of_sets’from C:/RubyFlickRaw.rb:36:in
from C:/Program Files/Ruby-2.0.0/lib/ruby/gems/2.0.0/gems/flickraw-0.9.6/lib/flickraw/response.rb:41:in
block in each'
each’from C:/Program Files/Ruby-2.0.0/lib/ruby/gems/2.0.0/gems/flickraw-0.9.6/lib/flickraw/response.rb:41:in
from C:/Program Files/Ruby-2.0.0/lib/ruby/gems/2.0.0/gems/flickraw-0.9.6/lib/flickraw/response.rb:41:in
each'
fetch_photos_of_sets’from C:/RubyFlickRaw.rb:33:in
from C:/RubyFlickRaw.rb:58:in `’
aさん。
コメントありがとうございます。
Windowsで試したことがございませんでしたので、この機会にとRuby環境を作成し、試してみました。RubyはRumix 2(http://ruby.morphball.net)を使わせていただき、2.0.0p247を入れ、gem install flickrawでははaさんと同じ0.9.6が入りました。また、変数base_dirと、35行目の末尾のディレクトリ表現にスラッシュの代わりに円マーク円マークとしました。
この環境でProアカウントを継続しているアカウントと古くからの無料アカウントの両方で動作いたしました。
うーん、なんとか再現できないものかと今度は別のアカウントを作成してやってみましたが、url_oでのエラーが出ませんでした。というわけで、現時点で解決できず申し訳ございません。引き続き、調べてみます。
返信ありがとうございます。
Rumix 2に入れ替えました。
上に書いてるコードの35行目にはスラッシュは含まれていないので、おそらく34行目のことだと思いますが、
(/[?”\\\*|]/,”_”) + ‘/’を
(/[?”\\\*|]/,”_”) + ‘\’や’\\’にしたり
色々試行錯誤してもエラーでダメでした。
flickrawだけではエラーが出るので、flickraw-cachedもインストールする必要があるようです。
rubyプログラムが動く環境の方は一緒だと思うので、windows用に編集したrbファイルの方をアップしていただき、api_keyなど必要な箇所だけ入力する形にすればフォーマットの間違えもなく確実だと思います。
同じエラーですが、前に貼ったとき何故か最後の部分だけちゃんと張られていなかったので、念のため貼りなおします。
$ D:\RubyFlickRaw.rb
d:/rubyflickraw.rb:37:in
block (2 levels) in fetch_photos_of_sets': undefined method
url_o’ for # (NoMethodError)from d:/rubyflickraw.rb:36:in
each'
block in fetch_photos_of_sets’from d:/rubyflickraw.rb:36:in
from C:/rumix/ruby/2.0.0/i386-mingw32/lib/ruby/gems/2.0.0/gems/flickraw-0.9.6/lib/flickraw/response.rb:41:in
block in each'
each’from C:/rumix/ruby/2.0.0/i386-mingw32/lib/ruby/gems/2.0.0/gems/flickraw-0.9.6/lib/flickraw/response.rb:41:in
from C:/rumix/ruby/2.0.0/i386-mingw32/lib/ruby/gems/2.0.0/gems/flickraw-0.9.6/lib/flickraw/response.rb:41:in
each'
fetch_photos_of_sets’from d:/rubyflickraw.rb:33:in
from d:/rubyflickraw.rb:58:in `’
[…] の通りにやって 4 つの文字列を入手しましょう。 RubyでFlickrの画像をまとめてダウンロード・バックアップしておく | 望遠鏡ドットコム それからユーザ ID も事前に調べておいてくださ […]
[…] ください。 詳細は前回のエントリでもご紹介した RubyでFlickrの画像をまとめてダウンロード・バックアップしておく | 望遠鏡ドットコム のエントリの通りにやるだけで大丈夫です。 準 […]
a様
半年間、気になりながらも手を付けられなかったのですが、Windows環境での動作確認を別にポストいたしました。正規表現のところをちょっとかえました。