2010-06-25 20 views
26

Tôi có điều này:Lỗi với urlencode trong 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) 

Và đó nâng cao một ngoại lệ:

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) 

và với 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) 

Làm thế nào tôi có thể sửa chữa nó?

Trả lời

55

Thư viện urlencode mong đợi dữ liệu ở định dạng str và không xử lý tốt với dữ liệu Unicode vì nó không cung cấp cách chỉ định mã hóa. Hãy thử điều này thay vì:

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) 

Những gì tôi đã làm là đảm bảo rằng tất cả các dữ liệu được mã hóa thành str sử dụng UTF-8 trước khi đi qua từ điển vào urlencode chức năng.

+0

bạn đã lưu tôi!: D – John

+0

Được sử dụng cho thông báo lỗi - unicodeencodeerror 'ascii' codec không thể mã hóa ký tự u '\ xb4'. Thanks –

+0

Đây là sai và đưa ra cùng một lỗi ... – Cerin

3

vấn đề là bạn muốn truyền một chuỗi unicode thành chuỗi, nhưng có một số ký tự phải được chuyển đổi thành ASCII trước. Vì vậy, tôi sẽ hướng dẫn bạn để tìm kiếm chuỗi mà không phải là ASCII và sau đó mã hóa chúng như sau:

cố gắng để thay đổi ví dụ nơi v là unicode-chuỗi:

quote_plus(str(v)) 

để

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

rằng sẽ giúp


Nếu bạn không phải sử dụng Python 2.x, bạn có thể chuyển sang Python 3.x, trong đó tất cả các chuỗi là unicode theo mặc định. Nhưng bạn phải chuyển đổi một số thứ cho nó (bạn có thể tự động hóa bên này hoặc đầy đủ với 2to3).

+0

Tôi nghĩ rằng, nhưng là một chút khó chịu vì là cốt lõi của python:/ – diegueus9

+0

hmm .. Tôi không nghĩ rằng đó là lỗi của urllib. maybie có bất cứ nơi nào một chuỗi, nó không được mã hóa thành ASCII. Bạn có thể tìm kiếm điều đó hoặc cung cấp thêm mã không? – Joschua

+0

nếu bạn nhìn thấy traceback bạn có thể đọc ngoại lệ được nêu ra trong /usr/lib/python2.5/urllib.pyc – diegueus9

4

Vấn đề là một số giá trị trong chuỗi mp3_data của bạn là chuỗi unicode không thể được biểu diễn trong mã hóa mặc định được sử dụng bởi urlencode() (trong khi những người khác là ASCII và vẫn là số nguyên khác). Bạn có thể sửa lỗi này bằng cách mã hóa các giá trị đó trước khi chuyển chúng đến urlencode(). On line 14 của /home/diegueus9/workspace/playku/src/client/playkud/service.py, trong make_request(), hãy thử thay đổi này:

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

này:

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

không phải tất cả các giá trị đều là chuỗi, điều này không hoạt động – diegueus9

+0

Chúng không phải là chuỗi để làm việc này. chuỗi đơn giản để unicode trước khi mã hóa như utf-8. Nếu nó thực sự không hoạt động, tôi muốn được nhìn thấy những gì thất bại trông giống như (Bạn có chắc bạn trả lời câu trả lời đúng?) –

8

Nếu bạn là bằng cách sử dụng Django, hãy xem lớp QueryDict của Django, nó có một phương thức urlencode().

Hoặc, đối với chức năng trợ giúp, bạn có thể sử dụng urlencode. Về cơ bản nó thực hiện những gì được mô tả trong các câu trả lời khác như một trình bao bọc xung quanh urllib.encode ban đầu.

+0

Mặc dù tôi không thông báo op là sử dụng django, tôi đã, và tìm thấy câu trả lời này rất hữu ích Hãy để tôi đề nghị một chỉnh sửa để xây dựng – tutuDajuju

+0

ok, tôi đến đây trong khi tìm kiếm lỗi django. – chhantyal

Các vấn đề liên quan