最終更新:
kitamomonga 2010年09月10日(金) 10:06:30履歴
Mechanize が使用するユーティリティメソッドを集めたクラスです。
特にインスタンスは無く、クラスメソッドの集合体として扱われます。
- CODE_DIC - detect_charset 用の文字エンコーディング名データ
- build_query_string - POSTやGET送信用のデータ配列を受け取って連結し文字列で返す
- to_native_charset - Nokogiri 使用時に対象文字列を UTF-8 に変換する
- from_native_charset - Nokogiri 使用時に対象文字列を UTF-8 から指示文字エンコーディングへと変換する
- detect_charset - 対象文字列の文字エンコーディングを NKF で推測して文字列名で返す
- html_unescape - HTMLエスケープされている文字を通常のUTF-8な文字に変換して返す
Mechanize::Util.detect_charset で使用する、NKF.guess の結果と返り値用文字列のペアの Hash です。
- HTML 中に meta 要素の charset が存在しない
- レスポンスヘッダのContent-Typeにもcharsetがない
- 上記の場合の Mechanize の推測結果が常に間違っているが Mechanize::Page#encoding= は使いたくない
「推測結果がNKF::SJISだったときに使用される名前はCP932じゃないと大変まずい」というような場合は
Mechanize::Util::CODE_DIC['SJIS'] = 'CP932'などと、「日本語サイトじゃないので推測結果のNKF::SJISは軒並み誤判定で実際はISO-8859-2」というときは
Mechanize::Util::CODE_DIC['SJIS'] = 'ISO-8859-2'のようにすることができます。
POST フォーム送信用のデータや GET 送信用のクエリ配列を、application/x-www-form-urlencoded で送信可能な文字列に変換して返します。
引数の parameters は送信データの名前と値のペアが含まれたネストした配列(か、{名前=>値}のHash)です。名前と値はそれぞれ CGI.escape でエスケープされたあとに = で連結され、それをさらに & で連結されます。
irb> p Mechanize::Util.build_query_string({'n1' => 'v1', 'n2' => 'tilde~~~'})
"n1=v1&n2=tilde%7E%7E%7E"
以下を除く文字はすべてパーセントエンコードされます。- 英字
- 数字
- 普通のハイフンマイナス「-」(U+002D)、普通のアンダースコア「_」(U+005F)、普通のピリオド「.」(U+002E)
- 普通の半角空白「 」(U+0020)
英字と数字とハイフン・アンダースコア・ピリオドはそのままですが、半角空白はそのままではなくふつうのプラス「+」(U+002B)に変換されます。HTML 4.01 のフォーム送信時の application/x-www-form-urlencoded でのエスケープ仕様(参考和訳)を参照してください。
application/x-www-form-urlencoded でエンコードされていることになっていますが、厳密には「別に問題はないけどちょっと余分」です。RFC 3986 的にはパーセントエンコードしなくてもいいものもパーセントエンコードしています(URI の query 部としてパーセントエンコードしなければならない文字はすべてパーセントエンコードされているので実際上の問題はありません)。
この返り値のプラス記号「+」はパーセントエンコードしないことをお勧めします。
| C.es | CGI.escape |
| U.es | URI.escape |
| W.es | WEBrick::HTTPUtils.escape |
| W.fe | WEBrick::HTTPUtils.form_escape |
| rfc3986 | 新しいほうの URI RFC |
| C.es | U.es | W.es | W.fe | rfc3986 | |
| SP | + | %20 | %20 | + | |
| - | |||||
| _ | |||||
| . | |||||
| ! | %21 | sub-delims | |||
| ~ | %7E | ||||
| * | %2A | sub-delims | |||
| ' | %27 | sub-delims | |||
| ( | %28 | sub-delims | |||
| ) | %29 | sub-delims | |||
| ; | %3B | %3B | sub-delims | ||
| / | %2F | %2F | gen-delims | ||
| ? | %3F | %3F | gen-delims | ||
| : | %3A | %3A | gen-delims | ||
| @ | %40 | %40 | gen-delims | ||
| & | %26 | %26 | sub-delims | ||
| = | %3D | %3D | sub-delims | ||
| + | %2B | %2B | sub-delims | ||
| $ | %24 | %24 | sub-delims | ||
| , | %2C | %2C | sub-delims | ||
| < | %3C | %3C | %3C | %3C | |
| > | %3E | %3E | %3E | %3E | |
| # | %23 | %23 | %23 | %23 | gen-delims |
| % | %25 | %25 | %25 | %25 | |
| " | %22 | %22 | %22 | %22 | |
| { | %7B | %7B | %7B | %7B | |
| } | %7D | %7D | %7D | %7D | |
| | | %7C | %7C | %7C | %7C | |
| \ | %5C | %5C | %5C | %5C | |
| ^ | %5E | %5E | %5E | %5E | |
| [ | %5B | %5B | %5B | gen-delims | |
| ] | %5D | %5B | %5D | gen-delims | |
| ` | %60 | %60 | %60 | %60 | |
| C.es | U.es | W.es | W.fe |
POST フォーム送信時の文字列を組み立てる Mechanize::Form#request_data か、ふつうの GET の params を送信先 URI の uri.query に反映させる Mechanize::Chain::ParameterResolver? 内で使用されます。ただし、multipart POST 送信(FileUploadを伴うもの)のファイル送信部分はここでは扱わず Mechanize::Form#request_data 内で処理されています。
文字列 str の文字エンコーディングを、Iconv 経由で orig_encoding から UTF-8 へと変換します。
現在使用されていないメソッドです。
Mechanize.html_parser が Nokogiri ではない場合は str を変換せずに返します。nil が渡された場合は nil を返します。変換は Iconv で行われ、str の文字エンコーディングが引数の orig_encoding で明示的に指定されなかった場合には Mechanize::Util.detect_charset で str の文字エンコーディングの推測が行われます。
文字列 str の文字エンコーディングを、Iconv 経由で UTF-8 から dest_encoding へと変換します。
ただし、Mechanize.html_parser が Nokogiri ではない場合、str か dest_encoding のどちらかに nil が渡された場合、何らかの理由で変換中の Iconv が Iconv::InvalidEncoding を発生させた場合、str を変換せずに返します。
第 1引数 str は変換したい文字列を指定します。
第 2引数 dest_encoding は変換先の文字エンコーディング名を Iconv が解釈可能な文字列か Ruby1.9 の Encoding オブジェクトで指定します。
変換自体は Iconv.iconv そのままで、要は
return Iconv.iconv(dest_encoding.to_s, 'UTF-8', str).join('')
です。Mechanize::Form#build_query 内で、GET や POST のフォーム送信用文字列をそのフォームのあるページの文字エンコーディングに変換するのに使用されます。この場合、dest_encoding は Mechanize::Page#encoding です。
引数文字列の文字エンコーディングを NKF.guess で推測して、Iconv 解釈可能な文字エンコーディング名で返します。
文字列に nil を指定した場合はおそらく ISO-8859-1 が返ります。str に対する NKF.guess の結果が JIS、EUC、SJIS、UTF8/16/32 以外だった場合は ISO-8859-1 が返ります。Mechanize::Util::CODE_DIC を使用しているので、問題がある場合はペアを追加したりしてください。
推測に NKF.guess を使用しているため、Ruby 1.8 ではいわゆる Latin の文字エンコーディング推測は不可能です。SHIFT_JIS か ISO-8859-1 のどちらかだと判断されると思われます。
Ruby1.9 の場合は str が force_encoding されていようが丸つき数字が入っていようが SHIFT_JIS と WINDOWS-31J をあっさり読み分けてくれます。Iconv 的には CP932 で返ってきてくれるととても嬉しいのですが。
引数の文字列に含まれる &str; や &0000; といった形の HTML エスケープの部分を実体に戻した文字列を返します。
HTML エスケープにマッチする部分が無かった場合はそのまま str が返ります。nil が渡された場合は nil が返ります。
Character entity references in HTML 4 にある文字実体参照と 10進数の数値文字参照が対象です。< も < も Ruby の pack('U') 経由で UTF-8 文字列の < に変換されます。< のような、&#x で始まる 16進数表現はそのままスルーされます。
参照部分が機械的に UTF-8 文字列に置換されるだけなので、もともとの str の文字エンコーディングは UTF-8 を強く推奨します。
Mechanize 1.0.0 現在、html_unescape が使用されているのは以下の場所です。
- Mechanize::Form#action のデフォルト値、HTML フォームに書かれていた action 属性値
- Mechanize::Chain::URIResolver#handle での、get や click に渡されていた引数 URL 全体
- Mechanize::Form::Field#name のデフォルト値、HTML の入力欄や選択メニュー等に書かれていた name 属性値
- Mechanize::Form::Field#value のデフォルト値、HTML の入力欄内部や選択メニュー等に書かれていた value 属性値
- Mechanize::Form::FileUpload#file_name のデフォルト値(HTML から読み込むのが未実装なのでスルー)
- Mechanize::Form::Option#value のデフォルト値、HTML の選択メニュー項目の value 属性値
