2014-02-15 41 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以暗示从一个例子,我从Request排除data和分别通过request and dataurlopen()。以下是更新的片段 -

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

我也分两步编码数据。你提到的代码工作正常。感谢您的反馈。 –

+1

啊,该死的,我刚才看到你回答了我自己〜30秒之前!那么,拍拍你自己的背部,并把你奉上! :) – Nil

+0

你能告诉我为什么选择utf-8吗?接收服务器如何知道你发送了utf-8而不是拉丁文-1? –