2014-02-15 42 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? –