# -*- coding: utf-8 -*- import urllib params = { 'key1': 'value1', 'key2': 'value2', 'key3': 'value3' } print urllib.urlencode(params)
を実行すると
key3=value3&key2=value2&key1=value1
のようにurlパラメータの形式に変換してくれて便利なurlencode
メソッドですが
引数のdict
にunicodeが含まれているとエラーになります。
例
# -*- coding: utf-8 -*- import urllib params = { 'key1': 'value1', 'key2': u'ほげ', 'key3': 'value3' } print urllib.urlencode(params)
結果
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
これを回避する話。
python2.7.5を使用しているので、python3系ではわかりません。
解決策
このあたりに解決策が。
どちらも、dict
の要素を1個ずつ取り出して一度encodeしてます。
書き方1
print urllib.urlencode(dict([k, v.encode('utf-8') if isinstance(v, unicode) else v] for k, v in params.items()))
書き方2
str_params = {} for k, v in params.items(): str_params[k] = unicode(v).encode('utf-8') print urllib.urlencode(str_params)
書き方1ではint
型など、.encode
が存在しない場合を考慮してこういう書き方になっているみたいですが
書き方2のようにunicode
で一旦全部unicodeにしちゃうとそれも気にしなくて済むんですね。
(全部unicode
かけることに問題はあるんだろうか...)
それぞれ1行と複数行で書き方を変えているのについては、特に理由はありません。
【朗報】Djangoを使ってる場合
フレームワークとしてDjango
を使っている場合
django.utils.http
のurlencode
メソッドを使いましょう。
Django Utils | Django documentation | Django
上の公式リファレンスによれば
A version of Python’s urllib.urlencode() function that can operate on unicode strings. The parameters are first case to UTF-8 encoded strings and then encoded as per normal.
とあるので、まさにこれ!といった感じです。 こっちを使う場合はunicodeの問題を全く気にせず、パラメータをそのまま渡せばOK。