2013-05-17 2 views
14

urlparse.parse_qs은 url 매개 변수를 구문 분석하는 데 유용하며 str으로 표시되는 간단한 ASCII URL로 올바르게 작동합니다. 그래서 내가 쿼리를 구문 분석 할 수 있습니다 다음 구문 분석 데이터에서 urllib.urlencode를 사용하여 동일한 경로를 구성 :Python urlparse.parse_qs unicode url

>>> 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 

또한 URL이 %에 비 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 

그러나 장고를 사용하여, 나는 request.get_full_path()를 사용하여 URL을 얻을, 그것은 unicode 문자열로 경로를 반환 : 지금 무슨 일이 일어날 지

>>> 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 

봐 :

>>> 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에는 바이트가 포함 된 유니 코드 문자열이 포함되어 있습니다. 유니 코드 포인트가 아닙니다! 은 물론 나는 UnicodeEncodeError있어, 해당 문자열을를 urlencode하려고 할 때 :

# just convert path, returned by request.get_full_path(), to `str` explicitly: 
path = str(request.get_full_path()) 

그래서 질문은 다음과 같습니다 :

  • 이유는 현재

    >>> 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) 
    

    나는 해결책을 가지고 parse_qs 너무 이상한 문자열 (바이트를 포함하는 유니 코드)를 반환합니까?

  • URL을 str로 변환하는 것이 안전합니까? 전에 다시 바이트 -

답변

16

인코딩 ASCII를 사용하여, .parse_qs()에 전달 :

query_dict = urlparse.parse_qs(query.encode('ASCII')) 

str()으로 만 명시 적으로 인코딩 같은 일을한다. 예, 안전합니다. URL 인코딩은 ASCII 코드 포인트 만 사용합니다 ().

parse_qs은 유니 코드 값이 전달되었으므로 유니 코드 값도 반환했습니다. 바이트를 해독하는 것은 일이 아닙니다.