2015-06-25 1 views
2

Я пытаюсь сделать URL-запрос в кодировке url в python 2.7, где я хочу отправить список словарей python, которые будут на сервере декодированы как список объектов JSON. В сущности, я делаю:как urlencode значение, которое является словарем python с закодированными символами юникода

>>>urllib.urlencode({"param":"val", "items":[item1, item2] }, True)

где item1 может быть что-то вроде { "a": u"š".encode("utf8") } (упрощено для примера)

Проблема возникает из-за символов Unicode.

Если item1 это само по себе закодированные, вы получите что-то значимое:

>>>urllib.urlencode(item1) 
'a=%C5%A1' 

однако, если я называю urllib.urlencode({"test": item1}) я получаю беспорядок:

'test=%7B%27a%27%3A+%27%5Cxc5%5Cxa1%27%7D' 

В этом случае юникода характер больше не кодируется как %C5%A1, а как более длинная последовательность, которая затем некорректно декодируется на стороне сервера.

Есть ли у кого-нибудь предложение правильно преобразовать значения словаря (т. Е. item1), прежде чем звонить urlencode, чтобы избежать этой проблемы?

+0

1. Что такое результат декодирования на стороне сервера? 2. Что вы ожидаете в результате «urllib.urlencode ({« test »: item1})'? – User

+0

Да, нет стандартного способа кодирования структурированного объекта, например, 'dict' в параметры запроса URL. В качестве крайней меры для того, чтобы ничего лучше делать, Python включил строковое представление объектного литерала, кодированную по URL-адресу версию '{'a': '\\ xc5 \\ xa1'}', но если ваш сервер -side приложение принимает структурированные объекты, вам нужно знать, какой пользовательский формат он хочет для них. – bobince

ответ

0

Я решил свою проблему первого призывающие json.dumps (пункт) для каждого элемента в пункте и затем вызовите urllib.urlencode.

Короче:

>>>urllib.urlencode({"param":"val", "items":[json.dumps(item) for item in items] }, True) 

Эта проблема была решена, потому что юникод символы затем кодируют с использованием \ ихххх которые могут быть на стороне сервера правильно декодированного с JSon анализатором.

+0

json.dumps работает в вашем случае. Но это не общее решение общей проблемы. Я думаю, что это должно быть исправлено в документах python: http://bugs.python.org/issue26433 – guettli

0

Так или иначе, вы должны расшифровать что-либо, закодированную до повторного кодирования Здесь есть один подход:

dictionary = {"test": item1} 
urllib.urlencode(dict([(k, decode_operation(v)) for k, v in dictionary.iteritems()])) 
+0

На самом деле unquote здесь не работает, вам нужна то, что когда-либо является обратной операцией вашей кодировки. –