2014-02-15 3 views
2

Я работаю над проектом django на основе Python 3. Я пытаюсь включить captcha. Я выбрал django-recaptcha, но, к сожалению, пакет не доступен для python3. Поэтому попробовал настроить порт на python3. Я сделал некоторые вещи 2to3 и сделал некоторые изменения по мере необходимости. Кажется, все работает отлично, за исключением url encoding for Request.Python-3 Ошибка кодирования параметра запроса

Следующий снипп доход POST data should be bytes or an iterable of bytes. It cannot be of type str. исключение.

def encode_if_necessary(s): 
    if isinstance(s, str): 
     return s.encode('utf-8') 
    return s 

params = urllib.parse.urlencode({ 
     'privatekey': encode_if_necessary(private_key), 
     'remoteip': encode_if_necessary(remoteip), 
     'challenge': encode_if_necessary(recaptcha_challenge_field), 
     'response': encode_if_necessary(recaptcha_response_field), 
     }) 

if use_ssl: 
    verify_url = "https://%s/recaptcha/api/verify" % VERIFY_SERVER 
else: 
    verify_url = "http://%s/recaptcha/api/verify" % VERIFY_SERVER 

request = urllib.request.Request(
    url= verify_url, 
    data=params, 
    headers={ 
     "Content-type": "application/x-www-form-urlencoded", 
     "User-agent": "reCAPTCHA Python" 
     } 
    ) 

httpresp = urllib.request.urlopen(request) 

Так что я пытался кодировать URL и другие вещи в request -

request = urllib.request.Request(
    url= encode_if_necessary(verify_url), 
    data=params, 
    headers={ 
     "Content-type": encode_if_necessary("application/x-www-form-urlencoded"), 
     "User-agent": encode_if_necessary("reCAPTCHA Python") 
     } 
    ) 

Но это дает urlopen error unknown url type: b'http исключение.

Кто-нибудь знает, как это исправить? Любая помощь приветствуется :).

ответ

2

Хорошо, я отвечу на это сам: P.

Принимая намеки из примера на python's official documentation, я исключил data из Request и отдельно прошел request and data в urlopen(). Ниже обновленный фрагмент -

params = urllib.parse.urlencode({ 
     'privatekey': encode_if_necessary(private_key), 
     'remoteip': encode_if_necessary(remoteip), 
     'challenge': encode_if_necessary(recaptcha_challenge_field), 
     'response': encode_if_necessary(recaptcha_response_field), 
     }) 

if use_ssl: 
    verify_url = "https://%s/recaptcha/api/verify" % VERIFY_SERVER 
else: 
    verify_url = "http://%s/recaptcha/api/verify" % VERIFY_SERVER 
# do not add data to Request instead pass it separately to urlopen() 
data = params.encode('utf-8') 
request = urllib.request.Request(verify_url) 
request.add_header("Content-type","application/x-www-form-urlencoded") 
request.add_header("User-agent", "reCAPTCHA Python") 

httpresp = urllib.request.urlopen(request, data) 

Despite of solving the problem I still do not know why the code generated by 2to3.py did not work. According to the documentation it should have worked.

0

Вы правильно догадались, вы должны кодировать данные, но не так, как вы это сделали.

Как писал @Sheena в this SO answer, вам необходимо 2 шага для кодирования вам данные:

data = urllib.parse.urlencode(values) 
binary_data = data.encode('utf-8') 
req = urllib.request.Request(url, binary_data) 

не на бис URL-адрес.

+0

Я тоже закодировал данные в 2 этапа. Код, который вы упомянули, отлично работает. Спасибо за ответ. –

+1

Ах, черт возьми, я только что видел, что ты ответил себе ~ за 30 секунд до того, как я это сделал! Ну, похлопайте себя по спине и поднимитесь! :) – Nil

+0

Можете ли вы рассказать мне, почему вы выбрали utf-8? Как получающий сервер знает, что вы отправили utf-8, а не, скажем, латинский-1? –

Смежные вопросы