読者です 読者をやめる 読者になる 読者になる

歩いたら休め

If the implementation is easy to explain, it may be a good idea.

【Ruby】open-uriでhttp=>httpsのリダイレクトを行う

Rubyスクレイピングしていたところ、PCサイトからスマホサイトにリダイレクトするところで次のようなエラーが出てしまいました。 どうやらRubyのopen-uriではhttpからhttpsへのリダイレクトが禁止されているようです。

kiito.hatenablog.com

open-uri.rb:224:in `open_loop': redirection forbidden: http://***.jp/***/ -> https://***/***/ (RuntimeError)

同じところで詰まっている人も多いらしく、リダイレクトを許可するためのgemも用意されていました。

qiita.com

github.com

ところが、いちいちgemを入れるのもアレな感じがしたので、他のやり方が無いか探してみました。 すると、「リダイレクトしない設定にするとOpenURI::HTTPRedirectエラーが発生するから、それをキャッチしてuriを取り出す方法もある」というのがStack Overflowに書いてました。

stackoverflow.com

先程のコードを直すと、こんな感じになるでしょうか?

def _fetch_url(url, user_agent, count=0)
  open(url, 'User-Agent' => user_agent, redirect: false)
rescue OpenURI::HTTPRedirect => e
  raise e if count >= MAX_RETRY
  _fetch_url(e.uri, user_agent, count+1)
rescue => e
  raise e if count >= MAX_RETRY
  sleep(SLEEP_TIME)
  _fetch_url(url, user_agent, count+1)
end

ただし、実際にはリダイレクト時にCookieを使う必要のある箇所もあり、 まだ未対応ですが、そこに対応するときにコードが煩雑になりそうだったのでおとなしくopen_uri_redirectionsを使わせてもらいました。 (前回訪問したページに合わせてコンテンツを出し分けているようです)

そもそもopen-uriではなく、スクレイピング向けのもっと高機能なライブラリを使うべきなのかもしれません。