python中的urlencode出错

时间:2010-06-25 20:23:38

标签: python encoding 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 个答案:

答案 0 :(得分:58)

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)

我所做的是确保在将字典传递到str函数之前,使用UTF-8将所有数据编码为urlencode

答案 1 :(得分:8)

如果您使用的是Django,请查看Django的QueryDict类,它有一个urlencode()方法。

或者,对于辅助函数本身,您可以使用urlencode。它基本上将其他答案中描述的内容作为原始urllib.encode的包装器。

答案 2 :(得分:4)

问题是你的mp3_data dict中的某些值是unicode字符串,无法用urlencode()使用的默认编码表示(而其他字符串是ASCII,还有一些是整数)。您可以通过在将这些值传递给urlencode()之前对其进行编码来解决此问题。在/home/diegueus9/workspace/playku/src/client/playkud/service.py的第14行,在make_request()中,尝试更改此内容:

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()))

答案 3 :(得分:3)

问题是,你想将unicode-string转换为字符串,但有些字符必须首先转换为ASCII。因此,我建议您搜索非ASCII字符串,然后按如下方式对其进行编码:

尝试更改例如,其中 v 是一个unicode-string:

quote_plus(str(v))

quote_plus(str(v.encode("utf-8")))

应该有帮助


如果您不必使用Python 2.x,则可以切换到Python 3.x,默认情况下所有字符串都是unicode。但你必须为它转换一些东西(你可以使用2to3自动完成这一方或完整。)