Ruby Mechanize: Basic認証でのエラー時の対応
あるBasic認証が必要なサイトでアクセスのタイミングの問題なのか、通常は認証もページ取得も問題ないのに、認証エラーが発生することがあった。
require 'mechanize' url = 'http://XXXX' username = 'XXXX' password = 'XXXX' agent = Mechanize.new agent.add_auth(url, username, password) agent.get(url)
として、以下の「Mechanize::UnauthorizedError」エラーが発生する。
`response_authenticate': 401 => Net::HTTPUnauthorized for http://XXXX -- Basic authentication failed -- available realms: XXXX HTTP BASIC LOGIN (Mechanize::UnauthorizedError)
add_authからgetまでのタイミングが早すぎるのかと間にsleepを入れたりしてみたが改善しない。また、同時刻に何度かアクセスを繰り返すと成功する場合もかなりあり、失敗する条件がはっきりしない。
このため、次のように例外設定を入れて、再試行もするようにしてみたが、
agent.add_auth(url, username, password) flag = 0 begin agent.get(url) rescue Mechanize::UnauthorizedError => e flag += 1 print "認証エラー: #{flag}" if flag <= 5 then sleep 1 retry end print "エラー:接続できませんでした。" exit end
結局は、いったんアクセスエラーになるとgetだけを再試行しても効果はないらしい。
そこで、add_authも含めて再試行することにした。
flag = 0 begin agent.add_auth(url, username, password) agent.get(url) rescue Mechanize::UnauthorizedError => e flag += 1 print "認証エラー: #{flag}" if flag <= 5 then sleep 1 retry end print "エラー:接続できませんでした。" exit end
こちらであれば、認証エラー時でも再試行でアクセスできるようになった。
リンク
- Ruby Mechanize Authentication – Stack Overflow
- Ruby::Basic Authentication by Mechanize | Memorandums Wiki&CMS
- 逆引きRuby – 例外
- 若手エンジニア/初心者のためのRuby 2.1入門(9):Rubyの例外とその捕捉――基本のbegin~rescue~endからensure、else、retry、後置rescueまで (3/4) – @IT
- 制御構造
- Exception: Mechanize::UnauthorizedError — Documentation for mechanize (2.7.3)