Подтвердить что ты не робот

Ошибка с urlencode в python

У меня есть это:

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': '[email protected]', '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)

Как я могу это исправить?

4b9b3361

Ответ 1

Библиотека 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': '[email protected]',
     '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.

Ответ 2

Если вы используете Django, посмотрите класс Django QueryDict, он имеет метод urlencode().

Или, для самой вспомогательной функции вы можете использовать urlencode. Он в основном делает то, что описано в других ответах, как обертка вокруг исходного urllib.encode.

Ответ 3

Проблема в том, что некоторые из значений в вашем dict_data dict - это строки unicode, которые не могут быть представлены в кодировке по умолчанию, используемой urlencode() (в то время как другие - ASCII, а другие - целые). Вы можете исправить это, закодировав эти значения, прежде чем передавать их в urlencode(). В строке 14 из /home/diegueus 9/workspace/playku/src/client/playkud/service.py в 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()))

Ответ 4

проблема заключается в том, что вы хотите наложить строку unicode на строку, но есть некоторые символы, которые нужно сначала преобразовать в ASCII. Поэтому я бы посоветовал вам искать строки, которые не являются ASCII, а затем кодировать их следующим образом:

попробуйте изменить , например, где v является строкой unicode для:

quote_plus(str(v))

к

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

что должно помочь


Если вам не нужно использовать Python 2.x, вы можете переключиться на Python 3.x, где по умолчанию все строки являются unicode. Но вам нужно преобразовать некоторые вещи для этого (вы можете автоматизировать эту вечеринку или заполнить ее с помощью 2to3).