Comment convertir un dictionnaire en chaîne de requête en Python?


Réponses:


158

Python 3

urllib.parse.urlencode(requête, doseq = Faux, [...])

Convertissez un objet de mappage ou une séquence de tuples à deux éléments, qui peuvent contenir des objets str ou bytes, en une chaîne de texte ASCII codée en pourcentage.

- Python 3 urllib.parsedocs

A dictest une cartographie.

Python hérité

urllib.urlencode( query[, doseq])
Convertit un objet de mappage ou une séquence de tuples à deux éléments en une chaîne «encodée en pourcentage» ... une série de key=valuepaires séparées par des '&'caractères ...

- Python 2.7 urllibdocs


1
C'est vrai, mais le dictrenvoyé par a cgi.parse_qs()en fait lists comme "valeurs". En les transmettant directement, vous obtiendrez des chaînes de requête très étranges.
Johnsyweb

Assez vrai. Cela m'apprendra à lire plus que la première phrase!
Johnsyweb


Le problème est que urlencode convertira l'espace en +, ce qui n'est pas recommandé.
user1633272

1
@ user1633272: Non recommandé selon qui?
Ignacio Vazquez-Abrams

67

En python3, légèrement différent:

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

production: 'pram1=foo&param2=bar'

pour la compatibilité python2 et python3, essayez ceci:

try:
    #python2
    from urllib import urlencode
except ImportError:
    #python3
    from urllib.parse import urlencode

7

Vous cherchez quelque chose exactement comme urllib.urlencode()!

Cependant, lorsque vous appelez parse_qs()(distinct de parse_qsl()), les clés du dictionnaire sont les noms de variable de requête uniques et les valeurs sont des listes de valeurs pour chaque nom.

Afin de transmettre ces informations urllib.urlencode(), vous devez "aplatir" ces listes. Voici comment vous pouvez le faire avec une liste de tuples:

query_pairs = [(k,v) for k,vlist in d.iteritems() for v in vlist]
urllib.urlencode(query_pairs)

16
Ou vous pourriez passer doseq=True.
Ignacio Vazquez-Abrams

@downvoter: Comment pourrais-je améliorer cette réponse? Cela fait six ans que je l'ai écrit!
Johnsyweb

-1

Peut-être que vous cherchez quelque chose comme ça:

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

Il prend un dictionnaire et le convertit en une chaîne de requête, tout comme urlencode. Il ajoutera un "&" final à la chaîne de requête, mais return query[:-1]corrige cela, si c'est un problème.


4
Avez-vous déjà rencontré str.join()? Et pourquoi pas urllib.quote_plus()?
Ignacio Vazquez-Abrams

1
@garbados Votre solution devrait fonctionner dans des cas simples. Cependant, jetez un œil urlencodedans urllib.py(cela devrait figurer dans votre installation Python) pour voir pourquoi la création d'une chaîne de requête n'est parfois pas aussi simple que votre réponse l'implique (en particulier la nécessité de `` citer '' certains caractères qui ne sont pas valides dans un URL). @Ignacio a également référencé deux fonctions qui nettoyeraient votre implémentation et la corrigeraient.
Anthony Cramp

Ah, en effet. Désolé pour la mise en œuvre grossière. Cela montre que je devrais être plus prudent en répondant à des questions auxquelles je ne me suis jamais posé.
garbados

Bien que ce ne soit peut-être pas la meilleure réponse, c'est exactement ce que je voulais voir lorsque j'ai cliqué sur le titre de cette question. Je n'ai que 4 éléments dans un dict que je dois transformer en une paire nom = valeur séparée par un «&». Mes valeurs sont contrôlées. Le str.join () est pratique dans mon cas mais je n'ai pas besoin de quote_plus (), encore une fois, car ce n'est pas du code public :) Merci!
harperville

1
@harperville mais la manière la plus correcte ( from urllib.parse import urlencode; urlencode(your_dict)) est plus courte et plus facile que ça! J'admets qu'il est parfois judicieux de réinventer la roue, même de façon médiocre, quand il est coûteux ou peu pratique d'accéder à des roues existantes et bien conçues, mais ici, utiliser la roue du commerce est plus facile et plus rapide que de rouler la vôtre. .
Mark Amery
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.