オープンデータとプログラミング

urlencodeでUnicodeEncodeErrorがでるときの原因と対処方法

事象

以下のような辞書に格納されたデータ

person_j1 = {“name”: u”山田 太郎”, “gender”: “male”, “age”: 18}

を次のようにurlエンコードした場合があります。

‘gender=male&age=18&name=%E5%B1%B1%E7%94%B0+%E5%A4%AA%E9%83%8E’

このときにurllibのurlencodeを使用すると次のようなエラーが発生する場合があります。

UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position 0-1: ordinal not in range(128)

原因

“name”: u”山田 太郎”のようにunicode文字列が含まれているとエラーになります。

実際の例

 
import urllib

person_e = {"name": "Taro Yamada", "gender": "male", "age": 18}
person_j1 = {"name": u"山田 太郎", "gender": "male", "age": 18}      #nameがunicode
person_j2 = {"name": "山田 太郎", "gender": "male", "age": 18}        #nameが文字列

urllib.urlencode(person_e)   #OK
urllib.urlencode(person_j1)  #NG
urllib.urlencode(person_j2)  #OK
 
 

以下のようにエラーになります。


UnicodeEncodeErrorTraceback (most recent call last)
<ipython-input-38-d6c34797cf92> in <module>()
      6 
      7 urllib.urlencode(person_e)   #OK
----> 8 urllib.urlencode(person_j1)  #NG
      9 urllib.urlencode(person_j2)  #OK
     10 

C:\Anaconda2\lib\urllib.pyc in urlencode(query, doseq)
   1341         for k, v in query:
   1342             k = quote_plus(str(k))
-> 1343             v = quote_plus(str(v))
   1344             l.append(k + '=' + v)
   1345     else:

UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)

対処方法

unicode文字列だけ’utf-8’だけエンコードしてやります
数字に対しては.encode(‘utf-8’)できないので、unicode文字列だけencodeしてあげるのがポイントです。

 
 
 

import urllib

person_j1 = {"name": u"山田 太郎", "gender": "male", "age": 18}

person_j1 = dict([k, v.encode('utf-8') if isinstance(v, unicode) else v] for k, v in person_j1.items())
urllib.urlencode(person_j1)  #OK



 
 
 

Pythonでディープラーニングを始めるなら以下の本がおすすめです。

アマゾンならこちら

楽天ならこちら

Comments are closed.