Как преобразовать словарь в строку запроса в Python?

Ответы:

159

Python 3

urllib.parse.urlencode(запрос, доза = ложь, [...])

Преобразуйте объект сопоставления или последовательность двухэлементных кортежей, которые могут содержать объекты str или bytes, в текстовую строку ASCII с процентной кодировкой.

- Документы Python 3urllib.parse

A dict- отображение.

Устаревший Python

urllib.urlencode( query[, doseq])
Преобразование объекта сопоставления или последовательности двухэлементных кортежей в строку «с процентным кодированием» ... серию key=valueпар, разделенных '&'символами ...

- Документы Python 2.7urllib

Игнасио Васкес-Абрамс
источник
1
Это правда, но на самом деле в качестве «значений» dictвозвращается s. Их прямая передача приведет к очень странному виду строк запроса. cgi.parse_qs()list
Johnsyweb
Достаточно верно. Это научит меня читать больше, чем первое предложение!
Johnsyweb
18
urllib.parse.urlencode в Python 3.
Denilson Sá Maia
Проблема в том, что urlencode преобразует пробел в +, что не рекомендуется.
user1633272
1
@ user1633272: Кто не рекомендует?
Игнасио Васкес-Абрамс
67

В python3 немного по-другому:

from urllib.parse import urlencode
urlencode({'pram1': 'foo', 'param2': 'bar'})

вывод: 'pram1=foo&param2=bar'

для совместимости с python2 и python3 попробуйте следующее:

try:
    #python2
    from urllib import urlencode
except ImportError:
    #python3
    from urllib.parse import urlencode
Джонни Чжао
источник
7

Вы ищете что - то точно , как urllib.urlencode()!

Однако при вызове parse_qs()(отличном от parse_qsl()) ключи словаря представляют собой уникальные имена переменных запроса, а значения представляют собой списки значений для каждого имени.

Чтобы передать эту информацию urllib.urlencode(), вы должны «сгладить» эти списки. Вот как это можно сделать с помощью списка кортежей:

query_pairs = [(k,v) for k,vlist in d.iteritems() for v in vlist]
urllib.urlencode(query_pairs)
Johnsyweb
источник
17
Или ты мог пройти doseq=True.
Игнасио Васкес-Абрамс
@downvoter: Как мне улучшить этот ответ? Я написал это шесть лет назад!
Johnsyweb
-1

Может быть, вы ищете что-то вроде этого:

def dictToQuery(d):
  query = ''
  for key in d.keys():
    query += str(key) + '=' + str(d[key]) + "&"
  return query

Он берет словарь и преобразует его в строку запроса, как и urlencode. Он добавит последний символ «&» к строке запроса, но return query[:-1]исправит это, если это проблема.

Гарбадос
источник
4
Вы str.join()еще не встречались ? Как насчет urllib.quote_plus()?
Игнасио Васкес-Абрамс
1
@garbados Ваше решение должно работать в простых случаях. Однако загляните urlencodeв urllib.py(это должно быть в вашей установке Python), чтобы понять, почему создание строки запроса иногда не так просто, как предполагает ваш ответ (в частности, необходимость `` цитировать '' определенные символы, которые недопустимы в URL). @Ignacio также сослался на две функции, которые очистят вашу реализацию и сделают ее правильной.
Энтони Крэмп
Ах, конечно. Извините за грубую реализацию. Это показывает, что я должен быть более осторожным, отвечая на вопросы, с которыми никогда не сталкивался сам.
garbados
Хотя это может быть не лучший ответ, это именно то, что я хотел увидеть, когда нажимал на заголовок этого вопроса. У меня есть только 4 элемента в dict, которые мне нужно преобразовать в пару имя = значение, разделенную знаком '&'. Мои ценности находятся под контролем. В моем случае str.join () удобен, но мне опять же не нужна quote_plus (), потому что это не общедоступный код :) Спасибо!
harperville
1
@harperville, но более правильный способ ( from urllib.parse import urlencode; urlencode(your_dict)) короче и проще этого! Я допускаю, что иногда разумно изобретать колесо, даже некачественно, когда доступ к существующим, хорошо спроектированным колесам дорого или неудобно, но здесь использовать готовое колесо проще и быстрее, чем катать собственное, некачественное. .
Марк Эмери