【问题标题】:Python-3 Request parameter encoding errorPython-3 请求参数编码错误
【发布时间】:2014-03-14 19:04:45
【问题描述】:

我一直在从事基于Python 3django 项目。我正在尝试合并captcha。我选择了django-recaptcha,但不幸的是该包不适用于python3。所以试图为python3定制它。我做了一些2to3 的东西,并根据需要进行了一些更改。除了url encoding for Request,一切似乎都正常。

执行 sn-p 会产生 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)

所以我尝试对request中的url和其他内容进行编码-

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 异常。

有人知道怎么解决吗?任何帮助表示赞赏:)。

【问题讨论】:

    标签: django python-3.x captcha


    【解决方案1】:

    好吧,我会自己回答这个问题:P。

    python's official documentation 的示例中获取提示,我从Request 中排除了data,并分别将request and data 传递给urlopen()。下面是更新的sn-p -

    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.

    【讨论】:

      【解决方案2】:

      你猜对了,你需要对数据进行编码,但不是你做的方式。

      正如@Sheena 在this SO answer 中所写,您需要两个步骤来对数据进行编码:

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

      并且不要再添加 url。

      【讨论】:

      • 我也分两步对数据进行了编码。你提到的代码工作正常。感谢您的反馈。
      • 啊,该死的,我刚刚看到你比我早 30 秒回答了自己!好吧,拍拍自己的后背并为你投票! :)
      • 你能告诉我你为什么选择 utf-8 吗?接收服务器如何知道您发送的是 utf-8 而不是 latin-1?
      • 我正在向我自己的服务器发送一个请求,所以我知道我在等待什么。我认为你应该知道,通过 API 或发给负责人的电子邮件。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-17
      • 1970-01-01
      • 2013-07-25
      • 2015-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多