MAGAZINE
ルーターマガジン
RubyでのURLエンコード方法とURI.encodeの代替手段
弊社では開発言語として主にRubyを使用し、クローリングやスクレイピングを業務として行っています。その過程で、プログラム内でURLを扱うことが多々あります。特にURLエンコードは正確なデータ取得や通信の安全性を保つために重要な処理の一つです。
RubyでURLをエンコードする方法を検索するとURI.encode
を利用する例が多く見られますが、現在は非推奨またはバージョンによっては機能そのものが削除されています。
今回は、URI.encode
の基本的な使い方と他の代替手段を紹介します。
基本的なURI.encode
の使い方
URI.encode
は、ストリングをURLエンコードするために使われていました。以下が使用例になります。
require 'uri'
original_url = "https://example.com/search?q=テスト&lang=ja"
encoded_url = URI.encode(original_url)
puts encoded_url
# 結果: https://example.com/search?q=%E3%83%86%E3%82%B9%E3%83%88&lang=ja
URI.encode
は標準仕様に基づき、URLの一部をエンコードします。
URLをエンコードする理由
URLエンコードは、URL内に含まれる特殊文字や非ASCII文字を正確に伝えるために重要です。たとえば、空白や&
、?
のような記号がそのまま含まれると、サーバーが正しく解釈できない可能性があります。URLエンコードを行うことで、これらの文字を安全に送信できる形に変換します。
例:
https://example.com/search?q=hello world
→https://example.com/search?q=hello%20world
https://example.com/product?name=カメラ(デジタル)
→https://example.com/product?name=%E3%82%AB%E3%83%A1%E3%83%A9%28%E3%83%87%E3%82%B8%E3%82%BF%E3%83%AB%29
(日本語、括弧(, )のエンコード)
このように、エンコードは通信の安全性と正確性を保つために必要です。
なぜURI.encode
は非推奨なのか
URI.encode
は、しばしばエンコードすべきでない文字もエンコードしてしまったり、一部の情報が欠落してしまうことがあります。たとえば下記のような場合があります。
require 'uri'
original_url_with_semicolon = "https://example.com/search?q=item1;item2"
encoded_url_with_semicolon = URI.encode(original_url_with_semicolon)
puts encoded_url_with_semicolon
# 結果: https://example.com/search?q=item1%3Bitem2
# ';' はエンコードされ、セミコロンが区切り文字として解釈されなくなる
original_url_with_fragment = "https://example.com/search?q=test#section"
encoded_url_with_fragment = URI.encode(original_url_with_fragment)
puts encoded_url_with_fragment
# 結果: https://example.com/search?q=test%23section
# '#' はフラグメントのはずだが、エンコードされてしまう
このような想定外のエンコードが問題を生じるため、URI.encode
は非推奨とされるようになりました。なお、URI.encode
はRuby 1.9以降非推奨となり、Ruby 3.0で削除されました。
以下では URI.encode
の代替手段をいくつか紹介します。
URI::DEFAULT_PARSER.escape
require 'uri'
original_url = "https://example.com/search?q=テスト&lang=ja"
escaped_url = URI::DEFAULT_PARSER.escape(original_url)
puts escaped_url
# 結果: https://example.com/search?q=%E3%83%86%E3%82%B9%E3%83%88&lang=ja
メリット:
- Ruby標準ライブラリに含まれており、追加のインストールが不要。
URI.encode
に近いシンプルな操作感。
デメリット:
- URL全体のエンコードに適しているが、クエリパラメータ専用ではない。
Addressable::URI
require 'addressable/uri'
original_url = "https://example.com/search?q=テスト&lang=ja"
escaped_url = Addressable::URI.encode(original_url)
puts escaped_url
# 結果: https://example.com/search?q=%E3%83%86%E3%82%B9%E3%83%88&lang=ja
メリット:
- 高度なカスタマイズが可能。
- 非標準的な要件にも対応できる柔軟性。
デメリット:
- 外部ライブラリのため、追加のインストールが必要で標準ライブラリに比べて依存が増える。
CGI.escape
require 'cgi'
query = "q=テスト&lang=ja"
escaped_query = CGI.escape(query)
puts escaped_query
# 結果: q%3D%E3%83%86%E3%82%B9%E3%83%88%26lang%3Dja
メリット:
- クエリ文字列のエンコードに最適。
- Ruby標準ライブラリに含まれており、インストールが不要。
デメリット:
- URL全体のエンコードには不向き。
- クエリパラメータ以外の部分で使用する際に制約が多い。
URI.encode_www_form
require 'uri'
params = { "q" => "テスト", "lang" => "ja" }
encoded_query = URI.encode_www_form(params)
puts encoded_query
# 結果: q=%E3%83%86%E3%82%B9%E3%83%88&lang=ja
メリット:
- クエリパラメータの生成とエンコードを簡素化。
- ハッシュや配列を直接エンコードできる。
デメリット:
- URL全体ではなく、クエリパラメータ専用。
- クエリ文字列以外で使用する際に制限がある。
まとめ
URI.encode
は非推奨であり、Ruby 1.9以降非推奨、Ruby 3.0で削除された。- 代替の方法として、
URI::DEFAULT_PARSER.escape
やaddressable
、CGI.escape
、URI.encode_www_form
を使用する。 - URLのエンコードは用途に基づいた正確な方法を選ぶことが重要。
RubyでURLを扱う際にはぜひ気にしてみてください。
CONTACT
お問い合わせ・ご依頼はこちらから