Url dekoduje UTF-8 w Pythonie

245

Sporo czasu spędziłem w Pythonie.
Jak mogę kiedykolwiek zdekodować taki adres URL:

example.com?title=%D0%BF%D1%80%D0%B0%D0%B2%D0%BE%D0%B2%D0%B0%D1%8F+%D0%B7%D0%B0%D1%89%D0%B8%D1%82%D0%B0

do tego w Pythonie 2.7: example.com?title==правовая+защита

url=urllib.unquote(url.encode("utf8")) zwraca coś bardzo brzydkiego.

Nadal nie ma rozwiązania, każda pomoc jest doceniana.

posiadacz miecza
źródło
2
W ogólnym przypadku ogon adresu URL jest po prostu plikiem cookie. Nie możesz wiedzieć, jakiego lokalnego zestawu znaków koduje serwer, ani nawet czy adres URL koduje ciąg znaków, czy coś zupełnie innego. (To prawda, wiele adresów URL zrobić zakodować ciąg postaci czytelnej dla człowieka, a często można odgadnąć kodowanie bardzo łatwo, ale nie jest to możliwe w przypadku ogólnie lub całkowicie automatycznie.).
tripleee

Odpowiedzi:

398

Dane są bajtami zakodowanymi w UTF-8, które mają znaki ucieczki z cytowaniem adresów URL, więc chcesz zdekodować za pomocą urllib.parse.unquote(), który obsługuje dekodowanie z danych zakodowanych w procentach do bajtów UTF-8, a następnie w sposób transparentny:

from urllib.parse import unquote

url = unquote(url)

Próbny:

>>> from urllib.parse import unquote
>>> url = 'example.com?title=%D0%BF%D1%80%D0%B0%D0%B2%D0%BE%D0%B2%D0%B0%D1%8F+%D0%B7%D0%B0%D1%89%D0%B8%D1%82%D0%B0'
>>> unquote(url)
'example.com?title=правовая+защита'

Odpowiednikiem w Pythonie 2 jest urllib.unquote(), ale to zwraca bajtowanie, więc musisz zdekodować ręcznie:

from urllib import unquote

url = unquote(url).decode('utf8')
Martijn Pieters
źródło
Dlaczego więc znak + pozostaje w ciągu? Myślałem, że% 2B był znakiem +, a literały + zostały usunięte podczas dekodowania?
AlexLordThorsen
5
@Rawrgulmuffins +to przestrzeń w x-www-form-urlencodeddanych ; użyjesz go urllib.parse.parse_qs()do parsowania tego lub użyj urllib.parse.unquote_plus(). Ale powinny one pojawiać się tylko w ciągu zapytania, a nie w pozostałej części adresu URL.
Martijn Pieters
140

Jeśli używasz Python 3, możesz użyć urllib.parse

url = """example.com?title=%D0%BF%D1%80%D0%B0%D0%B2%D0%BE%D0%B2%D0%B0%D1%8F+%D0%B7%D0%B0%D1%89%D0%B8%D1%82%D0%B0"""

import urllib.parse
urllib.parse.unquote(url)

daje:

'example.com?title=правовая+защита'
pavan
źródło
używając tego i otrzymując dict zamiast ciągu zapytania w python3.8
Clocker