はじめに
今回初めて Mechanize gem を使いました。
Cookies の永続化には Mechanize::CookieJar#save
メソッドを使って YAML 形式で保存するのが一般的なのだと思われます。
ですが、この save
メソッドは引数が IO
かファイル名である必要があります。 Heroku などではローカルファイルが cycle 時に消えてしまいますので、このメソッドを使っても消えてしまいます。これでは役に立ちません。
では Heroku で使うときに、外部サービスへ Cookies を保存するにはどうすればいいか、例えば Redis に保存するにはどうすればいいか、を確認する作業を行いましたので記録しておきます。
Mechanize インスタンス生成
require 'mechanize'
agent = Mechanize.new
Redis To Go 設定
外部サービスとして 今回は Redis To Go を選びました。(文字列が保存できるサービスであれば Redis 以外でも問題ないはずです。)
既に Redis To Go の登録が済んで おり、取得した Redis のアクセス URL が redis://redistogo:cdcddcfedd5ac469f64f4c44f7cc77bf@xxx.redistogo.com:9999/
であるとします。
require 'redis-objects'
redis_url = "redis://redistogo:cdcddcfedd5ac469f64f4c44f7cc77bf@xxx.redistogo.com:9999/"
Redis.current = Redis.new(url: redis_url)
cookies = Redis::Value.new('cookies')
なお Redis::Value
は文字列のみ保存可能なインスタンスで、セッター/ゲッターは Redis::Value#value= / Redis::Value#value です。
Cookies を保存
Mechanize
インスタンス agent
の Cookies を保存します。 Mechanize::CookieJar#save
メソッドに StringIO
インスタンスを渡すことにより文字列化します。
def cookies_to_yaml_string(agent)
cookies_io_write = StringIO.new("", 'r+')
agent.cookie_jar.save(cookies_io_write)
cookies_io_write.string
end
この cookies_to_yaml_string
メソッドを使うと、 Cookies を YAML 形式にした文字列が返されます。
セッターメソッドを使って保存します。今回の Redis の場合は cookies.value =
でセットします。
cookies.value = cookies_to_yaml_string(agent)
Cookies 設定
Cookies を Mechanize
インスタンス agent
に設定するには Mechanize::CookieJar#load
メソッドを使います。
def set_cookies(agent, cookies_yaml)
cookies_io_read = StringIO.new(cookies_yaml, 'r')
agent.cookie_jar.clear # 念のために Cookies を削除している
agent.cookie_jar.load(cookies_io_read)
end
この set_cookies
メソッドを使うと、 YAML 形式にした文字列の Cookies を agent
に設定することが出来ます。
ゲッターメソッドを使って Cookies の文字列を読み出し、設定します。今回は cookies.value
を用います。
set_cookies(agent, cookies.value)
おことわり
StringIO
クラスを使ったことが無いので、より良い使い方があればお教えください。よろしくお願いします。