python中的urlencode错误
我有这个:
a = {'album': u'Metamorphine', 'group': 'monoku', 'name': u'Son Of Venus (Danny\xb4s Song)', 'artist': u'Leandra', 'checksum': '2836e33d42baf947e8c8adef48921f2f76fcb37eea9c50b0b59d7651', 'track_number': 8, 'year': '2008', 'genre': 'Darkwave', 'path': u'/media/data/musik/Leandra/2008. Metamorphine/08. Son Of Venus (Danny\xb4s Song).mp3', 'user_email': 'diegueus9@gmail.com', 'size': 6624104}
data = urllib.urlencode(mp3_data)
然后这引发了一个异常:
Traceback (most recent call last):
File "playkud.py", line 44, in <module>
main()
File "playkud.py", line 29, in main
craw(args, options.user_email, options.group)
File "/home/diegueus9/workspace/playku/src/client/playkud/crawler/crawler.py", line 76, in craw
index(root, file, data, user_email, group)
File "/home/diegueus9/workspace/playku/src/client/playkud/crawler/crawler.py", line 58, in index
done = add_song(data[mp3file])
File "/home/diegueus9/workspace/playku/src/client/playkud/service.py", line 32, in add_song
return make_request(URL+'add_song/', data)
File "/home/diegueus9/workspace/playku/src/client/playkud/service.py", line 14, in make_request
data = urllib.urlencode(dict([k.encode('utf-8'),v] for k,v in mp3_data.items()))
File "/usr/lib/python2.5/urllib.py", line 1250, in urlencode
v = quote_plus(str(v))
UnicodeEncodeError: 'ascii' codec can't encode character u'\xb4' in position 19: ordinal not in range(128)
还有在ipython(2.5)中:
In [7]: urllib.urlencode(a)
UnicodeEncodeError Traceback (most recent call last)
/home/diegueus9/<ipython console> in <module>()
/usr/lib/python2.5/urllib.pyc in urlencode(query, doseq)
1248 for k, v in query:
1249 k = quote_plus(str(k))
-> 1250 v = quote_plus(str(v))
1251 l.append(k + '=' + v)
1252 else:
UnicodeEncodeError: 'ascii' codec can't encode character u'\xb4' in position 19: ordinal not in range(128)
我该怎么解决这个问题呢?
4 个回答
4
问题在于,你的mp3_data字典里有些值是无法用默认编码表示的unicode字符串(而其他的则是ASCII字符,还有一些是整数)。你可以通过在把这些值传给urlencode()
之前先进行编码来解决这个问题。在/home/diegueus9/workspace/playku/src/client/playkud/service.py文件的make_request()
函数的第14行,试着把这段代码:
data = urllib.urlencode(dict([k.encode('utf-8'),v] for k,v in mp3_data.items()))
改成这段代码:
data = urllib.urlencode(dict([k.encode('utf-8'),unicode(v).encode('utf-8')] for k,v in mp3_data.items()))
8
如果你在使用Django框架,可以看看Django的QueryDict类,它里面有一个叫做urlencode()的方法。
另外,你也可以直接使用这个帮助函数,urlencode
。这个函数基本上就是把其他回答中提到的功能封装了一下,实际上是对原来的urllib.encode的一个包装。
59
urlencode
库需要的数据格式是str
,而且它对Unicode数据处理得不好,因为它没有提供指定编码的方式。所以你可以试试下面的方法:
mp3_data = {'album': u'Metamorphine',
'group': 'monoku',
'name': u'Son Of Venus (Danny\xb4s Song)',
'artist': u'Leandra',
'checksum': '2836e33d42baf947e8c8adef48921f2f76fcb37eea9c50b0b59d7651',
'track_number': 8,
'year': '2008', 'genre': 'Darkwave',
'path': u'/media/data/musik/Leandra/2008. Metamorphine/08. Son Of Venus (Danny\xb4s Song).mp3',
'user_email': 'diegueus9@gmail.com',
'size': 6624104}
str_mp3_data = {}
for k, v in mp3_data.iteritems():
str_mp3_data[k] = unicode(v).encode('utf-8')
data = urllib.urlencode(str_mp3_data)
我做的就是在把字典传入urlencode
函数之前,确保所有数据都用UTF-8编码成str
格式。