725 votes

Comment encoder en URL une chaîne de requête en Python ?

Je suis en train d'encoder cette chaîne avant de la soumettre.

queryString = 'eventName=' + evt.fields["eventName"] + '&' + 'eventDescription=' + evt.fields["eventDescription"];

1262voto

Ricky Points 613

Python 2

Ce que vous recherchez est urllib.quote_plus:

safe_string = urllib.quote_plus('string_of_characters_like_these:$#@=?%^Q^$')

#Valeur: 'string_of_characters_like_these%3A%24%23%40%3D%3F%25%5EQ%5E%24'

Python 3

En Python 3, le paquet urllib a été divisé en composants plus petits. Vous utiliserez urllib.parse.quote_plus (notez le module enfant parse)

import urllib.parse
safe_string = urllib.parse.quote_plus(...)

8 votes

Merci! Dans mon cas cependant, j'ai besoin de mettre: import urllib.parse ... urllib.parse.quote_plus(query)

3 votes

Très bien, mais pourquoi n'utilisez-vous pas Unicode? Si la chaîne URL est Unicode, je dois l'encoder en UTF-8. Y a-t-il une autre façon de le faire?

8 votes

Cela fonctionne très bien, mais je n'ai pas pu accéder à certains services en ligne (REST) jusqu'à ce que j'ai ajouté ce paramètre safe = '/?:@&=+$,'

704voto

bgporter Points 11119

Vous devez passer vos paramètres dans urlencode() sous forme d'une table de hachage (dict), ou d'une séquence de 2-uplets, comme :

>>> import urllib
>>> f = { 'eventName' : 'myEvent', 'eventDescription' : 'cool event'}
>>> urllib.urlencode(f)
'eventName=myEvent&eventDescription=cool+event'

Python 3 ou supérieur

Utilisez urllib.parse.urlencode:

>>> urllib.parse.urlencode(f)
eventName=myEvent&eventDescription=cool+event

Remarquez que cela ne fait pas d'encodage d'URL dans le sens couramment utilisé (regarder la sortie). Pour cela, utilisez urllib.parse.quote_plus.

0 votes

J'étais sur le point de marquer résolu, j'ai trouvé la même solution. Merci.

16 votes

"Notez que urllib.urlencode ne fait pas toujours l'affaire. Le problème est que certains services se soucient de l'ordre des arguments, qui se perd lorsque vous créez le dictionnaire. Dans de tels cas, urllib.quote_plus est meilleur, comme l'a suggéré Ricky."

28 votes

Techniquement, c'est un bug dans les services, n'est-ce pas ?

40voto

dreftymac Points 7843

Contexte

  • Python (version 2.7.2)

Problème

  • Vous voulez générer une chaîne de requête urlencodée.
  • Vous avez un dictionnaire ou un objet contenant les paires nom-valeur.
  • Vous voulez pouvoir contrôler l'ordre de sortie des paires nom-valeur.

Solution

  • urllib.urlencode
  • urllib.quote_plus

Pièges

Exemple

Voici une solution complète, y compris comment gérer certains pièges.

### ********************
## initialiser python (version 2.7.2)
import urllib

### ********************
## d'abord configurer un dictionnaire de paires nom-valeur
dict_name_value_pairs = {
  "bravo"   : "True != False",
  "alpha"   : "http://www.example.com",
  "charlie" : "hello world",
  "delta"   : "1234567 !@#$%^&*",
  "echo"    : "user@example.com",
  }

### ********************
## configurer un ordre exact pour les paires nom-valeur
ary_ordered_names = []
ary_ordered_names.append('alpha')
ary_ordered_names.append('bravo')
ary_ordered_names.append('charlie')
ary_ordered_names.append('delta')
ary_ordered_names.append('echo')

### ********************
## afficher les résultats de sortie
if('NON, nous NE nous soucions pas de l'ordre des paires nom-valeur'):
  queryString  = urllib.urlencode(dict_name_value_pairs)
  print queryString 
  """
  echo=user%40example.com&bravo=True+%21%3D+False&delta=1234567+%21%40%23%24%25%5E%26%2A&charlie=hello+world&alpha=http%3A%2F%2Fwww.example.com
  """

if('OUI, nous NOUS soucions de l'ordre des paires nom-valeur'):
  queryString  = "&".join( [ item+'='+urllib.quote_plus(dict_name_value_pairs[item]) for item in ary_ordered_names ] )
  print queryString
  """
  alpha=http%3A%2F%2Fwww.example.com&bravo=True+%21%3D+False&charlie=hello+world&delta=1234567+%21%40%23%24%25%5E%26%2A&echo=user%40example.com
  """

34voto

Janus Troelsen Points 5121

27 votes

Je préfère urllib.parse.quote() moi-même car il utilise %20 plutôt que +.

21voto

user411279 Points 415

Notez que urllib.urlencode ne fonctionne pas toujours. Le problème est que certains services se soucient de l'ordre des arguments, ce qui est perdu lorsque vous créez le dictionnaire. Pour de tels cas, urllib.quote_plus est mieux, comme l'a suggéré Ricky.

2 votes

Il fonctionne bien et préserve l'ordre si vous passez une liste de tuples: >>> import urllib >>> urllib.urlencode([('name', 'brandon'), ('uid', 1000)]) 'name=brandon&uid=1000'

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X