2010-06-25 20 views
26

ho questo:Errore con urlencode in 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) 

E che sollevare un'eccezione:

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) 

e con 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) 

Come posso risolvere vero?

risposta

55

La libreria urlencode si aspetta dati nel formato str e non si adatta bene ai dati Unicode poiché non fornisce un modo per specificare una codifica. Prova a modificare:

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) 

Quello che ho fatto è stato assicurare che tutti i dati sono codificati in str usando UTF-8 prima di passare il dizionario nella funzione urlencode.

+0

mi hai salvato!: D – John

+0

Usato per il messaggio di errore - unicodeencodeerror 'ascii' codec non può codificare il carattere u '\ xb4'. Grazie –

+0

Questo è errato e dà lo stesso errore ... – Cerin

3

il problema è che si desidera eseguire il cast di una stringa unicode su una stringa, ma alcuni caratteri devono essere prima convertiti in ASCII. Quindi vi piacerebbe consiglio per la ricerca di stringhe che non sono ASCII e quindi codificare loro come segue:

cercare di cambiare ad esempio dove v è un unicode-stringa:

quote_plus(str(v)) 

a

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

che dovrebbe aiutare


Se non si deve utilizzare Python 2.x, è possibile passare a Python 3.x, dove tutte le stringhe sono unicode per impostazione predefinita. Ma devi convertire alcune cose per questo (puoi automatizzare questa festa o completare con 2to3).

+0

penso che, ma è un po 'brutto perché è nel cuore del pitone:/ – diegueus9

+0

hmm .. Io non credo che sia colpa del urllib. maybie c'è ovunque una stringa, che non è codificata in ASCII. Puoi cercarlo o fornire più codice? – Joschua

+0

se vedi il traceback che puoi leggere l'eccezione viene sollevata in /usr/lib/python2.5/urllib.pyc – diegueus9

4

Il problema è che alcuni valori nel dettato mp3_data sono stringhe unicode che non possono essere rappresentati nella codifica predefinita utilizzata da urlencode() (mentre altri sono ASCII e altri ancora sono numeri interi). Puoi risolvere questo problema codificando quei valori prima di passarli a urlencode(). On line 14 di /home/diegueus9/workspace/playku/src/client/playkud/service.py, in make_request(), provare a cambiare questo:

data = urllib.urlencode(dict([k.encode('utf-8'),v] for k,v in mp3_data.items())) 

a questo:

data = urllib.urlencode(dict([k.encode('utf-8'),unicode(v).encode('utf-8')] for k,v in mp3_data.items())) 
+0

non tutti i valori sono stringhe, questo non funziona. – diegueus9

+0

Non devono essere stringhe per far funzionare tutto ciò. Nota il mio uso della chiamata unicode() per convertire qualsiasi numero intero o semplici stringhe per unicode prima della codifica come utf-8. Se davvero non funziona, sarei interessato a vedere come si presenta l'errore (sei sicuro di aver risposto alla risposta giusta?) –

8

Se sei usando Django, dai un'occhiata alla classe QueryDict di Django, ha un metodo urlencode().

O, per la funzione di supporto in sé è possibile utilizzare urlencode. Fondamentalmente fa ciò che è descritto nelle altre risposte come un wrapper attorno all'originale urllib.encode.

+0

Anche se non ho notato op è usando django, lo ero, e ho trovato questa risposta molto utile! Lasciatemi suggerire una modifica per elaborare – tutuDajuju

+0

ok, sono venuto qui mentre cercavo l'errore django. – chhantyal