Як перетворити словник у рядок запиту на Python?


113

Як використовувати cgi.parse_qs(), як перетворити результат (словник) назад у рядок запиту? Шукаєте щось подібне urllib.urlencode().



Відповіді:


158

Пітон 3

urllib.parse.urlencode(запит, doseq = хибний, [...])

Перетворіть об’єкт відображення або послідовність двоелементних кортежів, які можуть містити str або байтові об'єкти, у текстовий рядок ASCII, кодований відсотками.

- Python 3 urllib.parseдок

A dict- це відображення.

Спадщина Python

urllib.urlencode( query[, doseq])
Перетворіть об’єкт відображення або послідовність двоелементних кортежів у рядок "закодованого у відсотках" ... ряд key=valueпар, розділених '&'символами ...

- Python 2.7 urllibдок


1
Це правда, але dictповернене cgi.parse_qs()фактично має list"свої" значення. Якщо передати їх прямо, то це призведе до дуже дивних рядків запитів.
Johnsyweb

Правда досить. Це навчить мене читати більше, ніж перше речення!
Johnsyweb


Проблема полягає в тому, що urlencode перетворить простір у +, що не рекомендується.
користувач1633272

1
@ user1633272: Не рекомендується, хто?
Ігнасіо Васкес-Абрамс

66

У 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

6

Ви шукаєте щось саме подібне 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)

15
Або ти міг пройти 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 також посилається на дві функції, які б очистили вашу реалізацію та зробили її правильною.
Ентоні Крамп

А, справді. Вибачте за жорстку реалізацію. Виявляю, що я повинен ретельніше відповідати на питання, з якими я ніколи не стикався.
гарбадос

Хоча це може бути не найкращою відповіддю, саме те, що я хотів побачити, натиснувши назву цього питання. У діктаті у мене всього 4 пункти, які мені потрібно перетворити на пару name = значення, розділену знаком "&". Мої значення контролюються. Str.join () є зручним у моєму випадку, але мені немає потреби в quo_plus (), знову ж таки, тому що це не публічний код :) Дякую!
Харпервіль

1
@harperville, але більш правильний спосіб ( from urllib.parse import urlencode; urlencode(your_dict)) коротший і простіший за цей! Я визнаю, що іноді розумно винаходити колесо, навіть з утрудненням, коли дорого або незручно отримати доступ до існуючих, добре сконструйованих коліс, але тут використання позаштатного колеса простіше та швидше, ніж прокат власного нижчого .
Марк Амеррі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.