Python urlparse.parse_qs unicode url
urlparse.parse_qs
est utile pour l'analyse des paramètres d'url, et il fonctionne très bien avec ASCII simple url, représentée par str
. Afin que je puisse analyser une requête et ensuite construire le même chemin à l'aide de urllib.urlencode
analysée à partir de données:
>>> import urlparse
>>> import urllib
>>>
>>> path = '/?key=value' #path is str
>>> query = urlparse.urlparse(path).query
>>> query
'key=value'
>>> query_dict = urlparse.parse_qs(query)
>>> query_dict
{'key': ['value']}
>>> '/?' + urllib.urlencode(query_dict, doseq=True)
'/?key=value' # <-- path is the same here
Il fonctionne aussi très bien, lorsque l'url contient pour cent codé non-ASCII param:
>>> value = urllib.quote(u'значение'.encode('utf8'))
>>> value
'%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B5'
>>> path = '/?key=%s' % value
>>> path
'/?key=%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B5'
>>> query = urlparse.urlparse(path).query
>>> query
'key=%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B5'
>>> query_dict = urlparse.parse_qs(query)
>>> query_dict
{'key': ['\xd0\xb7\xd0\xbd\xd0\xb0\xd1\x87\xd0\xb5\xd0\xbd\xd0\xb8\xd0\xb5']}
>>> '/?' + urllib.urlencode(query_dict, doseq=True)
'/?key=%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B5' # <-- path is the same here
Mais, lors de l'utilisation de django, j'obtiens l'url à l'aide de request.get_full_path()
, et il renvoie le chemin d'accès comme unicode
chaîne:
>>> path = request.get_full_path()
>>> path
u'/?key=%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B5' # path is unicode
Regardez ce qui va se passer maintenant:
>>> query = urlparse.urlparse(path).query
>>> query
u'key=%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B5'
>>> query_dict = urlparse.parse_qs(query)
>>> query_dict
{u'key': [u'\xd0\xb7\xd0\xbd\xd0\xb0\xd1\x87\xd0\xb5\xd0\xbd\xd0\xb8\xd0\xb5']}
>>>
query_dict
contient chaîne unicode, qui contient des octets! Pas unicode points!
Et bien sûr, j'ai un UnicodeEncodeError, lors de la tentative de urlencode cette chaîne:
>>> urllib.urlencode(query_dict, doseq=True)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python27\Lib\urllib.py", line 1337, in urlencode
l.append(k + '=' + quote_plus(str(elt)))
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-15: ordinal not in range(128)
Actuellement, j'ai une solution:
# just convert path, returned by request.get_full_path(), to `str` explicitly:
path = str(request.get_full_path())
Donc les questions sont:
- pourquoi parse_qs de retour si étrange chaîne de caractères (unicode, qui contient des octets)?
- est-il sécuritaire de convertir les url à la str?
OriginalL'auteur stalk | 2013-05-17
Vous devez vous connecter pour publier un commentaire.
Encoder retour d'octets avant passant à
.parse_qs()
, utilisant l'ASCII:Cela fait la même chose que
str()
mais avec un codage explicite. Oui, c'est sûr, l'URL utilise l'encodage ASCII codepoints seulement.parse_qs
a été remis une valeur Unicode, donc il est retourné vous une valeur unicode trop; il ne l'est pas du travail pour décoder octets.OriginalL'auteur Martijn Pieters