Vous avez une URL utilisant un schéma de codage non standard rejeté par les organismes de normalisation, mais toujours produit par certains codeurs. Le système Python urllib.parse.unquote()
ne peut pas les gérer.
Créer son propre décodeur n'est pas si difficile, heureusement. %uhhhh
les entrées sont destinées à être UTF-16 points de code ici, donc nous devons prendre paires de substituts en compte. J'ai également vu %hh
des points de code mélangés, pour plus de confusion.
En gardant cela à l'esprit, voici un décodeur qui fonctionne à la fois avec Python 2 et Python 3, à condition de passer un fichier str
dans Python 3 (Python 2 s'en soucie moins) :
try:
# Python 3
from urllib.parse import unquote
unichr = chr
except ImportError:
# Python 2
from urllib import unquote
def unquote_unicode(string, _cache={}):
string = unquote(string) # handle two-digit %hh components first
parts = string.split(u'%u')
if len(parts) == 1:
return parts
r = [parts[0]]
append = r.append
for part in parts[1:]:
try:
digits = part[:4].lower()
if len(digits) < 4:
raise ValueError
ch = _cache.get(digits)
if ch is None:
ch = _cache[digits] = unichr(int(digits, 16))
if (
not r[-1] and
u'\uDC00' <= ch <= u'\uDFFF' and
u'\uD800' <= r[-2] <= u'\uDBFF'
):
# UTF-16 surrogate pair, replace with single non-BMP codepoint
r[-2] = (r[-2] + ch).encode(
'utf-16', 'surrogatepass').decode('utf-16')
else:
append(ch)
append(part[4:])
except ValueError:
append(u'%u')
append(part)
return u''.join(r)
Cette fonction est fortement inspirée de la implémentation actuelle de la bibliothèque standard .
Démonstration :
>>> print(unquote_unicode('Tan%u0131m'))
Tanım
>>> print(unquote_unicode('%u05D0%u05D9%u05DA%20%u05DE%u05DE%u05D9%u05E8%u05D9%u05DD%20%u05D0%u05EA%20%u05D4%u05D8%u05E7%u05E1%u05D8%20%u05D4%u05D6%u05D4'))
איך ממירים את הטקסט הזה
>>> print(unquote_unicode('%ud83c%udfd6')) # surrogate pair