developer's diary

最近はc#のエントリが多いです

mechanizeを使って、Yahooブリーフケースのファイルを一括ダウンロードする。


yahooブリーフケースを一括でダウンロードするツールを探したのですが、見つからないので作ってみました。<追記_20081027>
yahooがブリーフケースの有料化によって無料でダウンロードが2009年2月1日までしかできないようです。

Yahoo!プレミアム、Yahoo! BBに会員登録いただいていない方は、2009年2月1日までの間に、お手数ですがYahoo!ブリーフケースにアップロードされているデータを、ご自分のパソコンにダウンロードしていただくか、Yahoo!プレミアム/Yahoo! BBへのご登録をお願いいたします。

プログラムとか苦手な人にでもわかるようにid:t_ash20さんが解説を書いてくれました。rubyが入ってない方はid:t_ash20さんの解説を見てがんばってみてください。Yahoo!ブリーフケースから一括ダウンロード その2 - perspective

少し修正しました。


インターネットストレージとしてのYahooブリーフケース - sshi.Continualでも自動化らしきことが書いていたので少しは需要があるのかな?

自動化ツールを使うことで、IDを抹消されても責任はとれませんのであしからず。

ソース

class YahooBriefcase

  require 'rubygems'
  require 'mechanize'
  require 'Kconv'
  require 'uri'

  BRIEFCASE_LOGIN_URL = "https://login.yahoo.co.jp/config/login?.src=bc&.done=http%3a//briefcase.yahoo.co.jp/&.intl=jp&.linkdone=http%3a//briefcase.yahoo.co.jp/"
  BRIEFCASE_LOGOUT_URL = "http://login.yahoo.co.jp/config/login?logout=1&.src=bc&.intl=jp&.done=http://briefcase.yahoo.co.jp"
  BRIEFCASE_URL = "http://briefcase.yahoo.co.jp/"

  def initialize(id=nil, password=nil, user_agent='Mechanize')

    @agent = WWW::Mechanize.new
    set_user_agent_alias(user_agent)
    briefcase_login(id,password) if id && password
  end

public

  # @param[in] user_agent ユーザエージェント
  def set_user_agent_alias(user_agent)
    @agent.user_agent_alias = user_agent
  end

  # @param[in] id Yahoo!のID
  # @param[in] password Yahoo!のパスワード
  def briefcase_login(id,password)
    @agent.post(BRIEFCASE_LOGOUT_URL)
    @agent.post(BRIEFCASE_LOGIN_URL, "login" => id, "passwd" => password)
  end


  # @param[in] dir ダウンロード先のディレクトリ
  # @param[in] url ダウンロード元のURL
  def all_get(dir, url=BRIEFCASE_URL)
    FileUtils.mkdir_p(dir)
    briefcase(dir,url,@agent)
  end

private

  def briefcase(name,url,agent)

    #fileが存在するurlの正規表現
    file_regexp = Regexp.new('^http://proxy')
    #ディレクトリのurlの正規表現
    dir_regexp = Regexp.new('&.order=&.view=l&.src=bc&.done=')

    infileArr = Array.new

    #現在の階層に存在するurlを取得
    page = agent.get(url)

    #取得したurlを回す。
    page.links.each do |link|

      #urlがディレクトリの場合
    if link.href =~ dir_regexp

        #ディレクトリの位置をinfileArrに入れる
        dirname = Kconv.tosjis(link.to_s).sub(/\n/,"").sub(/^ */,"")
        infileArr << { dirname => link.href }

        #urlがファイルの場合
        elsif link.href =~ file_regexp

        #ファイルの位置をinfileArrに入れる
        filename = Kconv.tosjis(URI.decode(link.href.to_s.sub(/\n/,"").to_s.sub(/\?.*$/,"").reverse.scan(/^(.*?)\//).to_s.reverse))
        infileArr << { filename => link.href }
      end
    end

    #現在の階層に存在するリンクを回す。
    infileArr.each do |dirhash|
      #リンクに対する名前、urlを取得(1回しか回らない)
      dirhash.each do |name2, url2|

        #urlがディレクトリの場合
        if url2 =~ dir_regexp then

          #ダウンロード先のディレクトリが存在しない場合は作成
          FileUtils.mkdir_p("#{name}/#{name2}")

          #再起呼び出し
          briefcase("#{name}/#{name2}",url2,agent)
          next
        end

        #urlがファイルの場合
        if url2 =~ file_regexp

          #ファイルを取得
          file = agent.get(url2)
          filename = Kconv.tosjis(name2).sub(/\n/,"")
          File.open("#{name}/#{name2}","w+b") do |line|
            line << file.body
          end
  
          #取得したファイル名を出力する。
          puts "#{name}/#{name2}"
        end
      end
    end
  end

end

[usage]使用方法

自分のIDのファイルを一括取得する場合
  id = 'id' #yahooのID
  password = 'pass' #yahooのパスワード
  dir = './briefcase' #ダウンロードする場所
  user_agent = 'Windows IE 6'  #ユーザエージェント

  yahooBriefcase = YahooBriefcase.new(id, password, user_agent)
  yahooBriefcase.all_get(dir)
他の人のファイルを一括取得する場合
  url = "http://briefcase.yahoo.co.jp/******" #公開している人のurl
  dir = './briefcase' #ダウンロードする場所

  yahooBriefcase = YahooBriefcase.new()
  yahooBriefcase.set_user_agent_alias('Windows Mozilla') #ユーザエージェントを変更
  yahooBriefcase.all_get(dir, url)

上記スクリプトはダウンロードのみです。。。

アップロードに関しては、Yahoo!ブリーフケース用のアップロード支援ツールで紹介しているようなツールを使えばいいのかな?


アップロードのツール作りはややこしそう。。。