47 votes

Codage/décodage des URL avec Python

J'essaie de coder, de stocker et de décoder des arguments en Python et je m'égare quelque part en chemin. Voici mes étapes :

1) J'utilise la boîte à outils Google. gtm_stringByEscapingForURLArgument pour convertir une NSString correctement pour la passer dans les arguments HTTP.

2) Sur mon serveur (python), je stocke ces arguments sous la forme de quelque chose comme u'1234567890-/:;()$&@".,?!\'[]{}#%^*+=_\\|~<>\u20ac\xa3\xa5\u2022.,?!\'' (notez qu'il s'agit des touches standard d'un clavier d'iphone dans la vue "123" et dans la vue "#+=", les touches \u et \x les caractères étant des préfixes monétaires comme la livre, le yen, etc.)

3) J'appelle urllib.quote(myString,'') sur cette valeur stockée, vraisemblablement pour les %-échapper pour le transport vers le client afin que le client puisse les dé-échapper.

Le résultat est que j'obtiens une exception lorsque j'essaie d'enregistrer le résultat de l'échappement des %. Y a-t-il une étape cruciale que j'ai négligée et qui doit être appliquée à la valeur stockée avec l'attribut \u et \x afin de le convertir correctement pour l'envoyer par http ?

Mise à jour : La suggestion marquée comme la réponse ci-dessous a fonctionné pour moi. Je fournis quelques mises à jour pour répondre aux commentaires ci-dessous pour être complet, cependant.

L'exception que j'ai reçue concernait un problème avec \u20ac . Je ne sais pas s'il s'agissait d'un problème spécifique, plutôt que du fait que c'était le premier caractère unicode de la chaîne.

Que \u20ac char est l'unicode du symbole "euro". J'ai constaté que j'avais des problèmes avec ce symbole à moins d'utiliser l'urllib2. quote méthode.

70voto

pycruft Points 8095

L'encodage url d'un unicode "brut" n'a pas vraiment de sens. Ce que vous devez faire, c'est .encode("utf8") d'abord, pour avoir un encodage d'octets connu, puis .quote() que.

La sortie n'est pas très jolie mais elle devrait être un encodage uri correct.

>>> s = u'1234567890-/:;()$&@".,?!\'[]{}#%^*+=_\|~<>\u20ac\xa3\xa5\u2022.,?!\''
>>> urllib2.quote(s.encode("utf8"))
'1234567890-/%3A%3B%28%29%24%26%40%22.%2C%3F%21%27%5B%5D%7B%7D%23%25%5E%2A%2B%3D_%5C%7C%7E%3C%3E%E2%82%AC%C2%A3%C2%A5%E2%80%A2.%2C%3F%21%27'

N'oubliez pas que vous devrez à la fois unquote() et decode() pour l'imprimer correctement si vous déboguez ou autre.

>>> print urllib2.unquote(urllib2.quote(s.encode("utf8")))
1234567890-/:;()$&@".,?!'[]{}#%^*+=_\|~<>€£¥•.,?!'
>>> # oops, nasty  means we've got a utf8 byte stream being treated as an ascii stream
>>> print urllib2.unquote(urllib2.quote(s.encode("utf8"))).decode("utf8")
1234567890-/:;()$&@".,?!'[]{}#%^*+=_\|~<>€£¥•.,?!'

C'est, en fait, ce que le fonctions django mentionnés dans une autre réponse le font.

Les fonctions django.utils.http.urlquote() et django.utils.http.urlquote_plus() sont des versions versions des fonctions standard de Python urllib.quote() et urllib.quote_plus() qui fonctionnent avec des caractères non ASCII. (Les données sont converties en UTF-8 avant l'encodage). l'encodage).

Si vous appliquez d'autres guillemets ou codages, veillez à ne pas fausser les choses.

4voto

flow Points 1376

Je voudrais appuyer la remarque de pycruft. les protocoles web ont évolué au fil des décennies, et la gestion des différents ensembles de conventions peut s'avérer fastidieuse. aujourd'hui, il se trouve que les URL ne sont pas explicitement définis pour les caractères, mais seulement pour les octets. par coïncidence historique, les URL sont l'un des endroits où l'on peut seulement supposer, mais pas imposer ou attendre en toute sécurité qu'un encodage soit présent. cependant, il existe une convention pour préférer latin-1 et utf-8 aux autres encodages ici. pendant un certain temps, cela ressemblait à ' pourcentages d'échappement unicode Ce serait l'avenir, mais ça n'a jamais marché.

il est primordial d'être pédant et pointilleux dans ce domaine sur la différence entre unicode et des objets en octet str ings (dans Python < 3.0 ; c'est, confusément, str des objets unicode et bytes / bytearray Malheureusement, d'après mon expérience, il est assez difficile, pour un certain nombre de raisons, de séparer proprement ces deux concepts dans Python 2.x.

encore plus OT, lorsque vous voulez recevoir des requêtes HTTP de tiers, vous ne pouvez pas absolument compter sur le fait que les URL sont envoyées en octets encodés en utf-8 et évidés en pourcentage : il peut y avoir de temps en temps un %uxxxx et au moins firefox 2.x avait l'habitude d'encoder les URL en latin-1 lorsque cela était possible, et en utf-8 uniquement lorsque cela était nécessaire.

2voto

almir karic Points 1

Vous n'avez pas de chance avec stdlib, urllib.quote ne fonctionne pas avec l'unicode. Si vous utilisez django, vous pouvez utiliser django.utils.http.urlquote qui fonctionne correctement avec l'unicode.

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